如何在视图模型中存储 linq 查询结果

Posted

技术标签:

【中文标题】如何在视图模型中存储 linq 查询结果【英文标题】:How to store linq query results in viewmodels 【发布时间】:2018-10-19 19:56:39 【问题描述】:

我有一个 linq 查询(在 Entity Framework Core 中),它连接两个 sql server 表,在 where 子句中过滤结果,然后从结果中选择一组列。

var resultsObj = (from rd in _db.ResData
                                  join ra in _db.ResAvailability on rd.RecNo equals ra.RecNoDate
                                  where ra.TotalPrice < Int32.Parse(resDeals.priceHighEnd) && ra.TotalPrice > Int32.Parse(resDeals.priceLowEnd)

                                  select new
                                  
                                      Name = rd.Name,
                                      ImageUrl = rd.ImageUrl,
                                      ResortDetails = rd.ResortDetails,
                                      CheckIn = ra.CheckIn,
                                      Address = rd.Address,
                                      TotalPrice = ra.TotalPrice
                                  );
                ViewBag.resultSet = resultsObj;

我创建了一个 viewmodel 类来存储属性一行查询结果和另一个 viewmodel 类,其中包含一个 List 对象来存储另一个 viewmodel 的所有实例,本质上用作从返回的所有行的集合查询:

public class ResortDataJoinObj

    public ResortData ResData  get; set; 
    public ResortAvailability ResAvail  get; set; 


public class ResortDealResultsObject

    public List<ResortDataJoinObj> resultsList  get; set; 

创建列表后,我需要将其导入视图页面,以便可以将查询结果存储在表中。我之前已经完成了获取查询结果的这个过程,除了存储过程,我能够遍历读取器对象并根据需要存储返回的行数据。我知道使用 Viewmodels 将数据从控制器传递到视图是标准做法,但我仍然是使用 linq 查询的新手,所以我不确定如何实际提取从 linq 查询结果返回的数据并绑定它到视图模型。

如何从 linq 查询结果中提取数据并将其存储在 viewmodel 类中?

【问题讨论】:

您需要控制器来处理它,并且您需要在视图中(在顶部)声明一个@model。见:***.com/questions/24469192/mvc-viewmodel-example MVC ViewModel example的可能重复 @AussieJoe 我查看了该帖子中的答案,但它似乎并没有真正解决这里的问题。在那个答案中,提供的代码只是将查询返回的属性分配给 viewmodel 对象,但只有一次。它不会遍历整个集合以提取每个“行”然后进行分配。您是否不必遍历整个集合以从每个返回的行中提取数据。 您需要在视图中使用“模型”。重新仔细查看示例并注意 html 中的 foreach 循环。据说,您正在尝试重新发明***。这是 MVC,它已经为你处理好了。就是这么简单:) 【参考方案1】:

由于您没有提供任何 HTML,请让我帮助另一个 SO answer:

@model IList<MySolution.Models.MyClassEtc>

@
    ViewBag.Title = "Home Page";
    Layout = "~/Views/Shared/_LayoutNoMenu.cshtml";



@foreach (var p in Model)
 
<div class="container">
@using (Html.BeginForm("About", "Home", FormMethod.Get, new  @class = "begin-form" ))

    <h1>Welcome</h1>
    <div class="required-field-block">
    <textarea rows="1" class="form-control" placeholder="Email" id="filter"></textarea>
    </div>
    <button class="btn btn-primary" type="submit">Login</button>

    @Html.TextBoxFor(model => model.ImageUrl, new  @class = "form-control" )

</div>
 

您需要在页面顶部定义一个视图模型。

@model IList<MySolution.Models.MyClassEtc>

你需要访问和迭代它,像这样:

@foreach (var p in Model)
 
    Debug.Write(p.Name);
    Debug.Write(p.ImageUrl); //etc

这么简单真的很棒,不是吗?

【讨论】:

我不需要视图代码方面的帮助,只需要控制器操作,但感谢您的示例。【参考方案2】:

我将如何做到这一点,将是通过创建一个类对象,该对象将具有您从返回的 linq 查询中想要的所有属性。 -

所以过程是,我们进行 linq 查询并获取 resultsObj 然后我们将有一个名为 ViewModelOfPage 的新类(我们将返回到页面的内容),它将包含我们想要返回的所有属性。

我们的班级看起来像 -

public class ViewModelOfPage


public string Name get;set;
public string ImageUrlget;set;
public string ResortDetails get;set;
public string CheckIn get;set;
public string Address get;set;
public int TotalPrice get;set; 

// this may be a double in your example or w/e value you want it set to.                                   

然后我们将在我们的控制器中创建这个类对象,使用我们通过 linq 查询返回的 obj 中的值对其进行初始化,然后将此对象发送到我们可以在视图中绑定其属性的页面。

所以在我们的控制器中,我们刚刚完成了 linq 查询并拥有了 resultsObj 对象。

然后我们将像这样初始化我们的视图模型:

ViewModelOfPage vm = new ViewModelOfPage


Name = resultsObj.Name,
ImageUrl = resultsObj.ImageUrl ,
ResortDetails = resultsObj.ResortDetails,
CheckIn = resultsObj.CheckIn,
Address = resultsObj.Address,
TotalPrice resultsObj.TotalPrice



return View("ourView",vm);

希望这有助于解释这个过程,这就是我将如何尝试这样做。如果有更好的方法请在下面解释:)

仅供参考,这是我的第一篇文章,所以我很可能以不正确的方式编写代码,所以我向大家道歉,因为他们在阅读它时可能会遇到痛苦:D 希望你们周二过得愉快。

如果您想将所有行返回到页面,您可以这样做:

List<ViewModelOfPage> vm = new ViewModelOfPage;
foreach (var row in resultsObj)

    //An example of only selecting certain results
    if(row.Name == "John" && row.TotalPrice > 15)
        var tempVm = new ViewModelOfPage
        
            Name = row.Name,
            ImageUrl = row.ImageUrl ,
            ResortDetails = row.ResortDetails,
            CheckIn = row.CheckIn,
            Address = row.Address,
            TotalPrice row.TotalPrice
        ;
        vm.add(tempVm);
    

view("ourview",vm);

【讨论】:

感谢您的回答。如果查询结果只返回一行,这似乎可行,因为您直接访问 resultsObj 的属性而不是遍历它。你知道整个 collection从查询返回的行可以存储? 您可以将其作为 ViewModelOfPage 的列表,然后将其作为视图中的 ienumerable 模型返回到页面,因此您的视图的第一行将是 @model IEnumerable 然后您可以在你的视图中,循环,并在视图中创建一个新的 div,包含相关信息和样式等 是的,它在视图中称为模型。您可以像这样迭代(在 Razor 语法中):@foreach (var p in Model.MyModelClass) 那么在控制器动作中,只需要从resultsObj中赋值一次?为什么不必遍历 resultsObj,使用 resultsObj 中的值实例化 ViewModelOfPage,将该实例插入到集合中,然后将该集合传递给视图? 一旦将模型传递给视图,就不再需要传递它。它现在在您的视图模型中,可以这样访问。它是您视野内的集合,因此得名 VIEW MODEL。

以上是关于如何在视图模型中存储 linq 查询结果的主要内容,如果未能解决你的问题,请参考以下文章

LINQ to SQL 将查询结果存储在变量中

如何在刷新表视图之前获取视图模型中的存储库列表?

如何将参数从 LINQ 查询传递到 SQL 视图?

如何在codeigniter中使用存储过程的结果集

如何将视图模型与 LINQ to Entities 一起使用

如何在 Web 服务 asp.net 中返回 linq to sql 查询结果?