如何将EF Core中LINQ查询结果存储到自定义ViewModel中?
如何将EF Core LINQ查询结果绑定到ViewModel并传递到视图
你现在的问题核心是把LINQ返回的匿名类型结果转换为你定义的强类型ViewModel,然后传递到视图渲染表格,我来帮你一步步调整:
1. 调整LINQ查询,返回强类型的ResortDataJoinObj
你当前的LINQ查询返回的是匿名对象,而你需要的是ResortDataJoinObj类型的实例。根据你的ViewModel结构,我们可以直接在select语句中构造这个类型的对象:
// 先提前解析价格范围,避免在LINQ查询中重复解析(提升性能且避免潜在SQL转换问题) int priceLow = Int32.Parse(resDeals.priceLowEnd); int priceHigh = Int32.Parse(resDeals.priceHighEnd); var resultsObj = from rd in _db.ResData join ra in _db.ResAvailability on rd.RecNo equals ra.RecNoDate where ra.TotalPrice < priceHigh && ra.TotalPrice > priceLow select new ResortDataJoinObj { ResData = new ResortData { Name = rd.Name, ImageUrl = rd.ImageUrl, ResortDetails = rd.ResortDetails, Address = rd.Address }, ResAvail = new ResortAvailability { CheckIn = ra.CheckIn, TotalPrice = ra.TotalPrice } };
备注:提前解析价格是因为EF Core会尝试把LINQ表达式转换为SQL,如果在查询里直接写
Int32.Parse,可能会导致无法转换的异常(除非开启客户端评估,但不推荐),提前解析会更稳妥。
2. 转换为List并封装到ResortDealResultsObject
LINQ查询默认返回的是IQueryable<T>(延迟执行,不会立即访问数据库),我们需要调用ToList()立即执行查询并得到内存中的集合,然后放到你的ResortDealResultsObject里:
var dealResults = new ResortDealResultsObject { resultsList = resultsObj.ToList() }; // 推荐用强类型视图传递模型,比ViewBag更安全易维护 return View(dealResults);
如果你还是想继续使用ViewBag,可以这样写:
ViewBag.resultSet = dealResults;
3. 在视图中遍历集合生成表格
假设你用的是Razor视图,首先在视图顶部指定模型类型(强类型视图):
@model ResortDealResultsObject
然后遍历resultsList生成表格:
<table border="1"> <thead> <tr> <th>度假村名称</th> <th>图片</th> <th>度假村详情</th> <th>入住日期</th> <th>地址</th> <th>总价</th> </tr> </thead> <tbody> @foreach (var item in Model.resultsList) { <tr> <td>@item.ResData.Name</td> <td><img src="@item.ResData.ImageUrl" alt="@item.ResData.Name" style="width:100px;" /></td> <td>@item.ResData.ResortDetails</td> <td>@item.ResAvail.CheckIn.ToString("yyyy-MM-dd")</td> <td>@item.ResData.Address</td> <td>@item.ResAvail.TotalPrice</td> </tr> } </tbody> </table>
如果用ViewBag传递,需要先转换类型再遍历:
@{ var results = ViewBag.resultSet as ResortDealResultsObject; } @if (results != null && results.resultsList.Any()) { <table border="1"> <!-- 上面的表格代码,把Model换成results即可 --> </table> }
可选:优化ViewModel设计
如果你的业务只需要查询返回的那些列,其实可以把ResortDataJoinObj改成只包含需要的属性,这样更轻量,代码也更简洁:
public class ResortDataJoinObj { public string Name { get; set; } public string ImageUrl { get; set; } public string ResortDetails { get; set; } public DateTime CheckIn { get; set; } public string Address { get; set; } public int TotalPrice { get; set; } }
对应的LINQ查询也可以简化:
select new ResortDataJoinObj { Name = rd.Name, ImageUrl = rd.ImageUrl, ResortDetails = rd.ResortDetails, CheckIn = ra.CheckIn, Address = rd.Address, TotalPrice = ra.TotalPrice };
这样视图里的代码也不需要嵌套访问ResData和ResAvail,直接用@item.Name这种方式即可。
内容的提问来源于stack exchange,提问作者loremIpsum1771
相关产品推荐
相关产品推荐

