【问题标题】:How to store linq query results in viewmodels如何在视图模型中存储 linq 查询结果
【发布时间】: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。见:stackoverflow.com/questions/24469192/mvc-viewmodel-example
  • MVC ViewModel example的可能重复
  • @AussieJoe 我查看了该帖子中的答案,但它似乎并没有真正解决这里的问题。在那个答案中,提供的代码只是将查询返回的属性分配给 viewmodel 对象,但只有一次。它不会遍历整个集合以提取每个“行”然后进行分配。您是否不必遍历整个集合以从每个返回的行中提取数据。
  • 您需要在视图中使用“模型”。重新仔细查看示例并注意 HTML 中的 foreach 循环。据说,您正在尝试重新发明轮子。这是 MVC,它已经为你处理好了。就是这么简单:)

标签: c# asp.net sql-server linq asp.net-core


【解决方案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 ImageUrl{get;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。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-08
  • 2012-03-13
  • 1970-01-01
  • 1970-01-01
  • 2012-07-27
相关资源
最近更新 更多