解决将LINQ Union查询结果传递到ASP.NET MVC视图时的模型不匹配错误
问题原因
- 你当前控制器返回的是
List<string>类型:LINQ查询中分别选择了doc.DocumentName和pho.PhotoName两个字符串字段做Union,最终返回的结果是字符串集合。 - 视图声明的接收模型是
IEnumerable<Document_Management_System.Models.Document>,两边类型不匹配,因此抛出类型转换错误。 - 额外问题:你原始SQL的逻辑是查询两张表的全字段,现有LINQ仅查询了名称字段,和原始需求不一致。
解决方案
方案一:仅需展示文件名称(最简修改)
直接修改视图的模型声明为字符串集合即可,控制器代码无需调整:
@model IEnumerable<string> @{ ViewBag.Title = "Test"; } <h2>Test</h2> <div class="panel-body"> <table class="zebra"> <tr> <th>文件名称</th> </tr> @foreach (var item in Model) { <tr> <td>@item</td> </tr> } </table> </div>
方案二:需同时展示文档、图片的多个字段(对齐原始SQL逻辑)
需要先定义公共视图模型统一存储两类文件的公共字段,再做Union查询。
1. 新增公共视图模型
在项目Models目录下新增UserUploadItem.cs类:
public class UserUploadItem { public string FileName { get; set; } public DateTime UploadTime { get; set; } public string FileType { get; set; } // 其他需要展示的公共字段可自行补充 }
2. 修改控制器查询逻辑
将文档、图片分别映射为公共视图模型后再做Union:
public ActionResult Test() { var result = (from doc in _context.Documents where doc.AddedBy == LogonUsername select new UserUploadItem { FileName = doc.DocumentName, UploadTime = doc.CreateTime, // 替换为你实际的文档上传时间字段名 FileType = "文档" }).Union (from pho in _context.Photos where pho.AddedBy == LogonUsername select new UserUploadItem { FileName = pho.PhotoName, UploadTime = pho.CreateTime, // 替换为你实际的图片上传时间字段名 FileType = "图片" }).ToList(); return View(result); }
3. 修改视图模型声明
@model IEnumerable<Document_Management_System.Models.UserUploadItem> @{ ViewBag.Title = "Test"; } <h2>Test</h2> <div class="panel-body"> <table class="zebra"> <tr> <th>@Html.DisplayNameFor(model => model.FileName)</th> <th>@Html.DisplayNameFor(model => model.UploadTime)</th> <th>@Html.DisplayNameFor(model => model.FileType)</th> </tr> @foreach (var item in Model) { <tr> <td>@Html.DisplayFor(modelItem => item.FileName)</td> <td>@Html.DisplayFor(modelItem => item.UploadTime)</td> <td>@Html.DisplayFor(modelItem => item.FileType)</td> </tr> } </table> </div>
注意事项
使用EF/EF Core做多表Union查询时,需要保证两个查询返回的类的字段名称、类型、顺序完全一致,否则会出现SQL转换异常。
内容的提问来源于stack exchange,提问作者rrpqertyu
相关产品推荐
相关产品推荐

