[英]Using virtual collection in C# to make code more efficient
你好,我有一个看起来像这样的模型,
public class Site
{
public int ID { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string Province { get; set; }
public string PostalCode { get; set; }
public virtual ICollection<OffSiteItemDetails> ItemDetails { get; private set; }
public virtual ICollection<SalesOrder> soDetails { get; private set; }
public virtual ICollection<SODetails> SODDetails { get; private set; }
public string IncomingTotalOSI(Site s)
{
PIC_Program_1_0Context db = new PIC_Program_1_0Context();
float? partCost = 0;
float? componentCost = 0;
float? itemCost = 0;
float? incomingCost = 0;
List<OffSiteItemDetails> d = ItemDetails.Where(x => x.siteID == s.ID).ToList();
var less30days = DateTime.Now.AddDays(-30);
//List<SalesOrder> so = soDetails.Where(x => x.OrderType == SOType.OffSiteInventory).Where(x => x.DateCreated > less30days).ToList();
List<SalesOrder> so = db.SalesOrders.Where(x => x.OrderType == SOType.OffSiteInventory).Where(x => x.DateCreated > less30days).ToList();
List<SODetails> sod = db.SODetails.Where(x => x.SiteID == s.ID).ToList();
foreach (var order in so)
{
foreach (var details in sod)
{
if (order.ID == details.SalesOrderID)
{
if (details.PartID != null){
partCost += details.part_qty * db.Parts.Where(x => x.ID == details.PartID).FirstOrDefault().AveCostPerUnit;
}
else if (details.ComponentID != null){
componentCost += details.comp_qty * db.Components.Where(x => x.ID == details.ComponentID).FirstOrDefault().AveCostPerUnit;
}
else{
itemCost += details.item_qty * db.Items.Where(x => x.ID == details.ItemID).FirstOrDefault().CostPerUnit;
}
}
}
}
incomingCost = partCost + componentCost + itemCost;
string cost = String.Format("{0:C}", incomingCost);
return cost;
}
}
但这效率低下,因为它多次循环访问同一数据集。 并且添加的订单越多,程序就会变得越慢。 我仍在学习 MVC 并研究了虚拟集合,但我仍然对如何在这种情况下提高程序效率感到困惑
首先,我建议从这一行中删除.ToList()
:
List sod = db.SODetails.Where(x => x.SiteID == s.ID).ToList();
当您在那里使用 ToList() 时,您将在该点强制对基础数据存储进行执行和枚举,而不是推迟执行,直到您确实需要枚举所需的结果。
然后更改以下行:
foreach (var details in sod)
到:
foreach (var details in db.SODetails .Where(x => x.SiteID == s.ID && details.SalesOrderID == order.ID))
当然,权衡是您通过查询每个销售订单来访问数据库,但您不会多次迭代相同的数据。
您还可以去掉最内层循环中的 if() 语句,只需将您的条件放在 Linq 中以限制循环的内容。 这也可以提高性能:
foreach (var details in sod.Where(detail => detail.SalesOrderID == order.ID)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.