You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:43:46