在C#中使用虚拟集合提高代码效率
你好,我有一个像这样的模型在C#中使用虚拟集合提高代码效率,c#,sql,asp.net-mvc,linq,C#,Sql,Asp.net Mvc,Linq,你好,我有一个像这样的模型 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 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;
}
}
公共类站点
{
公共int ID{get;set;}
公共字符串名称{get;set;}
公共字符串地址{get;set;}
公共字符串City{get;set;}
公共字符串省{get;set;}
公共字符串PostalCode{get;set;}
公共虚拟ICollection ItemDetails{get;private set;}
公共虚拟ICollection所需详细信息{get;private set;}
公共虚拟ICollection SODDetails{get;private set;}
公共字符串输入(站点s)
{
PIC_程序_1_0上下文db=新PIC_程序_1_0上下文();
浮动?部分成本=0;
浮动?组件成本=0;
浮动?项目成本=0;
浮动?收入成本=0;
List d=ItemDetails.Where(x=>x.siteID==s.ID).ToList();
var less30days=DateTime.Now.AddDays(-30);
//List so=soDetails.Where(x=>x.OrderType==SOType.OffSiteInventory).Where(x=>x.DateCreated>less30天).ToList();
列出so=db.SalesOrders.Where(x=>x.OrderType==SOType.OffSiteInventory).Where(x=>x.DateCreated>less30天).ToList();
List sod=db.SODetails.Where(x=>x.SiteID==s.ID).ToList();
foreach(so中的var顺序)
{
foreach(sod中的var详细信息)
{
if(order.ID==details.SalesOrderID)
{
if(details.PartID!=null){
partCost+=details.part\u数量*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;
}
否则{
itemCost+=details.item_数量*db.Items.Where(x=>x.ID==details.ItemID).FirstOrDefault().CostPerUnit;
}
}
}
}
收入成本=部件成本+部件成本+项目成本;
string cost=string.Format(“{0:C}”,incomingCost);
退货成本;
}
}
但这是低效的,因为它在同一数据集上循环多次。添加的订单越多,程序的运行速度就会越慢。我仍在学习MVC,并研究过虚拟收藏,但我仍不清楚如何在这种情况下使用它来提高程序的效率。首先,我建议从此行中删除
.ToList()
:
List sod=db.SODetails.Where(x=>x.SiteID==s.ID).ToList()代码>
当您在那里使用ToList()时,您将强制在该点对基础数据存储执行和枚举,而不是推迟执行,直到您实际需要枚举所需的结果
然后更改以下行:
foreach(sod中的var详细信息)
致:
foreach(变量详细信息在db.SODetails中
。其中(x=>x.SiteID==s.ID&&details.SalesOrderID==order.ID))
当然,折衷的办法是,您通过查询每个销售订单来访问数据库,但您不会对同一数据进行多次迭代
您还可以去掉最内部循环中的if()语句,只需将您的条件放在Linq中,以限制所循环的内容。这也可以提高性能:
foreach(sod.Where(detail=>detail.SalesOrderID==order.ID)中的变量详细信息)
您调用的每个LINQ方法都会迭代整个IEnumerable
。可能会从foreach
更改为for
,并在循环期间临时缓存值?我真的不知道,我不经常使用LINQ,因为这样的事情。请包括销售订单和销售订单详细信息模型。我相信你是一对多连接的?为什么销售订单不属于一个站点?如果父实体属于一个站点不是更好吗?假设你使用的是LINQ to SQL(而不是EF 6/EF Core),您可以使用Join
返回销售订单及其详细信息,这样您就不必为每个so
搜索sod
。或者,使用ToLookup
将sod
转换为查找,这样您就可以直接获得销售订单的详细信息。