在foreach循环中计数,最佳实践

本文关键字:最佳 foreach 循环 | 更新日期: 2023-09-27 18:13:18

我一直致力于在foreach循环中获得计数记录。我将需要在一个页面上运行许多这些计数。我正在寻找最有效的方法来做到这一点。

我已经走了这么远,但我不确定我是否走在正确的道路上。如果是,我怎么把数据放到我的视图中。

视图模型

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; }
}
控制器

 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);
}
}
视图

@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>
    }

我在我的视图上收到这个错误:对象引用没有设置为对象的实例。(在线:@foreach (var item in Model.AgentList))

我错过了什么?

谢谢。

在foreach循环中计数,最佳实践

var model = new AgtLeadStatsListVM();末尾的分号表示在该行之后您不再处于对象初始化器中。您可能正在尝试的语法更类似于以下内容:

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)))
    // ...
}
顺便说一下,如果您想在一次往返中获得所有这些信息,您可以使用基于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();

更新

从你的评论听起来这更像是你想要的:

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();

和你的视图代码:

@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>
    }

AgentList属性应该从你的模型中完全移除

我在我的视图上收到这个错误:对象引用未设置为an对象的实例。(在线:@foreach (var item in)Model.AgentList)

AgentList为空。

而且,你还没有正确初始化你的模型。

具体来说,这行代码

var model = new AgtLeadStatsListVM();

创建一个AgtLeadStatsListVM类型的新对象,其中

  • LoanAgent为null
  • LeadDate 1/1/0001 12:00:00 am
  • LeadDailyCt为0
  • LeadWeeklyCt为0
  • LeadMTDCt为0
  • LeadYTDCt为0
  • AgentList为null
  • WebLead is Lead

默认值,因为您没有设置任何值。可能,您想要使用对象初始化器,在那里您不需要();。我们这样写:

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.
}

我将忽略您得到的错误(请参阅其他答案),并且只参考最佳实践和计算部分问题的最有效方法。

最有效的方法(至少在我看来)是对结果使用一些缓存技术并每天更新缓存(因为您使用的最大分辨率是每天)。显然,选择合适的缓存机制取决于您的应用程序。它可以从在应用程序启动时将一些数据存储在静态变量中,到运行专用的Redis服务器(或任何其他快速数据结构存储)。这里的底线是:尽量减少对DB的查询数量,并缓存任何合适的数据。