我需要根据不同条件从单个列表中设置多个标签的值。这是我的代码:
List<RFPModel> lst = RFPModel.GetAll(); //ALL
if(lst.Count>0)
{
lblActive.InnerText = lst.Count(a => a.StatusID == (int)ProjectStatus.Project_Active).ToString();
lblCompleted.InnerText = lst.Count(a => a.StatusID == (int)ProjectStatus.Project_Completed).ToString();
lblProposal.InnerText = lst.Count(a => a.StatusID == (int)ProjectStatus.Proposal_UnderProcess).ToString();
lblProposalsRej.InnerText = lst.Count(a => a.StatusID == (int)ProjectStatus.Proposal_Rejected).ToString();
lblRFPRec.InnerText= lst.Count(a => a.StatusID == (int)ProjectStatus.RFP_Submitted).ToString();
lblRFPRef.InnerText= lst.Count(a => a.StatusID == (int)ProjectStatus.RFP_Rejected).ToString();
lblRFPApp.InnerText = lst.Count(a => a.StatusID == (int)ProjectStatus.RFP_Approved).ToString();
}
恐怕这种方法可能会影响性能,因为每次遍历列表时都需要一个值。任何对更好方法的建议将不胜感激。
答案 0 :(得分:6)
使用GroupBy
(最好是在数据库IQueryable
级别),然后可以使用ToDictionary
以获得更多的风味
var dict = lst.GroupBy(x => x.StatusID)
.Select(x => new { x.Key, count = x.Count() })
.ToDictionary(x => (ProjectStatus)x.Key, x => x.count.ToString());
lblActive.InnerText = dict[ProjectStatus.Project_Active];
lblCompleted.InnerText = dict[ProjectStatus.Project_Completed];
...
假设StatusID
与ProjectStatus
一对一映射
请注意,多余的Select
是多余的,但是如果您只是想要一个列表,则会添加
其他资源
对序列的元素进行分组。
将序列的每个元素投影为新形式。
Enumerable.ToDictionary Method
从IEnumerable创建字典。
答案 1 :(得分:2)
您可以执行以下操作,仅在列表中循环一次(这里我仅显示4个计数。您可以自己轻松添加其余计数):
int activeCount = 0;
int completedCount = 0;
int proposalCount = 0;
int proposalRejCount = 0;
foreach (var item in lst) {
if (item.StatusID == (int)ProjectStatus.Project_Active)
activeCount++;
else if (item.StatusID == (int)ProjectStatus.Project_Completed)
completedCount++;
else if (item.StatusID == (int)ProjectStatus.Project_UnderProcess)
proposalCount++;
else if (item.StatusID == (int)ProjectStatus.Project_Proposal_Rejected)
proposalRejCount++;
}
lblActive.InnerText = activeCount.ToString();
lblCompleted.InnerText = completedCount.ToString();
lblProposal.InnerText = proposalCount.ToString();
lblProposalRej.InnerText = proposalRejCount.ToString();
但是仅当此特定代码实际上导致性能问题时才这样做。不要过早优化。
答案 2 :(得分:1)
您可以像这样轻松使用ToLookup
:
List<RFPModel> lst = new List<RFPModel>();
lst.Add(new RFPModel { StatusID = 1 });
lst.Add(new RFPModel { StatusID = 1 });
lst.Add(new RFPModel { StatusID = 1 });
lst.Add(new RFPModel { StatusID = 2 });
lst.Add(new RFPModel { StatusID = 2 });
lst.Add(new RFPModel { StatusID = 3 });
lst.Add(new RFPModel { StatusID = 4 });
lst.Add(new RFPModel { StatusID = 4 });
lst.Add(new RFPModel { StatusID = 4 });
lst.Add(new RFPModel { StatusID = 4 });
lst.Add(new RFPModel { StatusID = 5 });
var lookup = lst.ToLookup(p => p.StatusID);
var status1Count = lookup[1].Count(); // 3
var status2Count = lookup[2].Count(); // 2
var status3Count = lookup[3].Count(); // 1
var status4Count = lookup[4].Count(); // 4
var status5Count = lookup[5].Count(); // 1
用适当的枚举替换 lookup [x] 部分中的 x 。
答案 3 :(得分:1)
查找将是一个很好的解决方案。
List<RFPModel> lst = RFPModel.GetAll(); //ALL
var lookup = lst.ToLookup(x=>x.StatusID);
lblActive.InnerText = lookup[(int)ProjectStatus.Project_Active].Count();
lblCompleted.InnerText = lookup[(int)ProjectStatus.Project_Completed].Count();
and so on ......
您可以阅读有关查询here
的更多信息