简体   繁体   English

MVC-计入foreach循环,最佳做法

[英]MVC - Count in a foreach loop, best practice

I have been working on getting a count records within a foreach loop. 我一直在努力获取foreach循环内的计数记录。 I am going to need run many of these counts on a single page. 我将需要在单个页面上运行许多这些计数。 I am looking for the most efficient way to do this. 我正在寻找最有效的方法。

I have gotten this far, but I am not sure if I headed down the right path. 我已经走了这么远,但是我不确定我是否走了正确的道路。 If I am, how do I get this data into my view. 如果是的话,如何将这些数据输入视图。

ViewModel 视图模型

public class AgtLeadStatsListVM
{
    public string LoanAgent { get; set; }
    public DateTime LeadDate { get; set; }
    public int LeadDailyCt { get; set; }
    public int LeadWeeklyCt { get; set; }
    public int LeadMTDCt { get; set; }
    public int LeadYTDCt { get; set; }
    public IEnumerable<MWFUser> AgentList { get; set; }
    public virtual WebLead Lead { get; set; }
}

Controller 调节器

 var model = new AgtLeadStatsListVM();            
 {
 // Get Selected Agent's Information
 var AgentList = from l in db.MWFUsers
                 where (l.UserTitle == "Banker"
                 select l;

    foreach (var agent in AgentList)
    {

    // Daily Lead Count
    var LeadDailyCt = db.WebLeads.Count(x => (x.LoanAgent == agent.UserEmail)
    && (x.LeadDate >= todayDate && x.LeadDate <= todayEndDay));

    // Weekly Lead Count
    var LeadWeeklyCt = db.WebLeads.Count(x => (x.LoanAgent == agent.UserEmail)
                                         && x.LeadDate >= firstOfWeek
                                         && x.LeadDate <= todayEndDay);

    // Monthly Lead Count
    var LeadMTDCount = db.WebLeads.Count(x => (x.LoanAgent == agent.UserEmail)
                                         && x.LeadDate >= firstOfMonth
                                         && x.LeadDate <= todayEndDay);

   // YTD Lead Count
   var LeadYTDCount = db.WebLeads.Count(x => (x.LoanAgent == agent.UserEmail)
                                         && x.LeadDate >= firstOfMonth
                                         && x.LeadDate <= todayEndDay);
}
}

View 视图

@model LoanModule.ViewModels.AgtLeadStatsListVM

<div>
    @foreach (var item in Model.AgentList)
    {
    <p>@Model.LoanAgent</p>
    <p>@Model.LeadDailyCt</p>
    <p>@Model.LeadWeeklyCt</p>
    <p>@Model.LeadMTDCt</p>
    <p>@Model.LeadYTDCt</p>
    }

I am receiving this error on my View: Object reference not set to an instance of an object. 我在“视图:对象引用”未设置为对象的实例上收到此错误。 (on line: @foreach (var item in Model.AgentList)) (在行上:@foreach(Model.AgentList中的var项))

What am I missing? 我想念什么?

Thank you. 谢谢。

The semicolon at the end of var model = new AgtLeadStatsListVM(); var model = new AgtLeadStatsListVM();末尾的分号var model = new AgtLeadStatsListVM(); means that you are no longer in an object initializer after that line. 意味着您在该行之后不再处于对象初始化器中。 The syntax you're probably trying for is something more along these lines: 您可能正在尝试使用的语法如下所示:

var agents = 
    from l in db.MWFUsers
    where l.UserTitle == "Banker"
    select l;

var model = new AgtLeadStatsListVM
{
    // Get Selected Agent's Information
    AgentList = agents.ToList(),
    // Daily Lead Count
    LeadDailyCt = agents.Sum(a => db.WebLeads.Count(
        x => (x.LoanAgent == a.UserEmail)
            && (x.LeadDate >= todayDate && x.LeadDate <= todayEndDay)))
    // ...
}

By the way, if you want to get all of this information in a single round-trip, you could use this group by -based trick. 顺便说一句,如果您想在一次往返中获取所有这些信息,则可以使用基于group by的技巧。

var model = 
    (from agent in agents
    let webLeads = db.WebLeads.Where(x => x.LoanAgent == agent.UserEmail)
    group new{agent, webLeads} by 0 into g
    select new AgtLeadStatsListVM
    {
        // Get Selected Agent's Information
        AgentList = g.Select(e => e.agent).ToList(),
        // Daily Lead Count
        LeadDailyCt = g.Sum(e => e.webLeads.Count(x => x.LeadDate >= todayDate && x.LeadDate <= todayEndDay)),
        // ...
    }).FirstOrDefault();

Update 更新

From your comments it sounds like this is more what you're going for: 从您的评论看来,这更是您要追求的目标:

var model = 
    (from agent in agents
    let webLeads = db.WebLeads.Where(x => x.LoanAgent == agent.UserEmail)
    select new AgtLeadStatsListVM
    {
        // Get Selected Agent's Information
        LoanAgent = agent.UserEmail,
        // Daily Lead Count
        LeadDailyCt = webLeads.Count(x => x.LeadDate >= todayDate && x.LeadDate <= todayEndDay),
        // ...
    }).ToList();

And your view code: 和您的视图代码:

@model IEnumerable<LoanModule.ViewModels.AgtLeadStatsListVM>

<div>
    @foreach (var item in Model)
    {
      <p>@item.LoanAgent</p>
      <p>@item.LeadDailyCt</p>
      <p>@item.LeadWeeklyCt</p>
      <p>@item.LeadMTDCt</p>
      <p>@item.LeadYTDCt</p>
    }

The AgentList property should be removed from your model entirely. 应该将AgentList属性从模型中完全删除。

I am receiving this error on my View: Object reference not set to an instance of an object. 我在“视图:对象引用”未设置为对象的实例上收到此错误。 (on line: @foreach (var item in Model.AgentList)) (在行上:@foreach(Model.AgentList中的var项))

The AgentList is null. AgentList为空。

Furthermore, you haven't initialized correctly your model. 此外,您还没有正确初始化模型。

Specifically, this line of code 具体来说,这行代码

var model = new AgtLeadStatsListVM();

creates a new object of type AgtLeadStatsListVM , where 创建一个类型为AgtLeadStatsListVM的新对象,其中

  • LoanAgent is null LoanAgent为空
  • LeadDate 1/1/0001 12:00:00 AM LeadDate 1/1/0001 12:00:00 AM
  • LeadDailyCt is 0 LeadDailyCt为0
  • LeadWeeklyCt is 0 LeadWeeklyCt为0
  • LeadMTDCt is 0 LeadMTDCt为0
  • LeadYTDCt is 0 LeadYTDCt为0
  • AgentList is null AgentList为空
  • WebLead is Lead WebLead是领导

The default values, since you didn't set any value. 默认值,因为您未设置任何值。 Probably, you want to make use of an object initializer, there you don't need (); 可能你想使用一个对象初始化器,那里你不需要(); . We write just this: 我们这样写:

var model = new AgtLeadStatsListVM
{
    LoadAgent = "Name of the LoadAgent",
    LeadDate = DateTime.Now.Utc,
    LeadDailyCt = agents.Sum(a => db.WebLeads.Count(
    x => (x.LoanAgent == a.UserEmail)
        && (x.LeadDate >= todayDate && x.LeadDate <= todayEndDay)))
    // Do the same for the rest of the corresponding properties.
}

I am going to ignore the error that you are getting (see other answers for it) and reference only best practice and a most efficient way for counting part of the question. 我将忽略您遇到的错误(请参见其他答案),仅引用最佳实践和计算部分问题的最有效方法

The most efficient way (at least in my opinion) would be using some caching technique for the result and updating the cache on daily basis(since the maximum resolution that you use is daily). 最有效的方法(至少在我看来)是对结果使用某种缓存技术并每天更新缓存(因为您使用的最大分辨率是每天)。 Clearly, choosing an appropriate caching mechanism depends on your application. 显然,选择合适的缓存机制取决于您的应用程序。 It can go from storing some data in static variable on application start, to running a dedicated Redis server (or any other fast data structure store). 它可以从在应用程序启动时将一些数据存储在静态变量中到运行专用的Redis服务器 (或任何其他快速数据结构存储)。 The bottom line here is: try to minimize the number of queries to DB and cache any suitable data. 最重要的是:尝试减少对数据库的查询数量并缓存任何合适的数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM