我目前正在尝试优化我的应用程序。AllProducts
包含约24k行(条目)。
List<tblMATProduct> AllProducts;
基本上,我想替换以下内容(ForEachAsync()
添加):
AllProducts = db.tblMATProduct.Include(s => s.tblGrade).Include(s => s.tblMATProductState).Include(s => s.tblFormat).Include(s => s.tblProduct).ThenInclude(s => s.tblBatch).OrderBy(s => s.MATProductID).ToList();
与类似:
AllProducts = db.tblMATProduct.Include(s => s.tblGrade).Include(s => s.tblMATProductState).Include(s => s.tblFormat).Include(s => s.tblProduct).ThenInclude(s => s.tblBatch).ForEachAsync(// Do operations here).OrderBy(s => s.MATProductID).ToList();
所有Includes都是必需的,因为我需要从主表开始的所有这些表中获取信息tblMATProduct
。
这将帮助我消除以下操作,这些操作由于不必要而非常昂贵foreach
(使用LINQ构建列表,然后再次加载以修改其对象)。
基本上,以下所有代码都用于修改List中的对象Allproducts
,我想将其移动到中ForEachAsync()
。
private void SetProductsListInfo()
{
foreach (var product in AllProducts)
{
SetNumLotCount(product);
SetProductTMD(product);
SetLimitedQuantityTags(product);
SetNFPATags(product);
}
}
private void SetNumLotCount(tblMATProduct product)
{
{
if (product.tblProduct != null && product.tblProduct.tblBatch != null)
{
product.ProductNumLotCount = "No. Lot (" + product.tblProduct.tblBatch.Count + ")";
}
else if (product.tblProduct == null)
{
}
else
{
product.ProductNumLotCount = "No. Lot (" + 0 + ")";
}
}
}
private void SetProductTMD(tblMATProduct product)
{
product.ProductTMD = new tblProductTMD();
product.DangerList = new List<tblDanger>();
product.ProductTransportClassList = new List<tblProductTransportClass>();
if (product.tblProduct != null)
{
product.ProductTMD = product.tblProduct.tblProductTMD.FirstOrDefault();
if (product.ProductTMD != null) product.DangerList = product.ProductTMD.tblDanger.ToList();
if (product.ProductTMD != null) product.ProductTransportClassList = product.ProductTMD.tblProductTransportClass.ToList();
}
product.DangerTypeList = new List<tblDangerType>();
if (product.DangerList != null)
{
foreach (var danger in product.DangerList)
{
if (danger.tblDangerType != null && danger.tblDangerType.RulingSystemID == 2) product.DangerTypeList.Add(danger.tblDangerType);
}
foreach (var dangerType in product.DangerTypeList)
{
if (dangerType != null) dangerType.DangerIcon = dangerType.DangerTypeIcon;
}
}
product.TransportClassList = new List<tblTransportClass>();
if (product.ProductTransportClassList != null)
{
foreach (var productTransportClass in product.ProductTransportClassList)
{
if (productTransportClass.tblTransportClass != null) product.TransportClassList.Add(productTransportClass.tblTransportClass);
}
}
}
private void SetLimitedQuantityTags(tblMATProduct product)
{
if (product.ProductTMD != null && product.ProductTMD.ProductTMDLimitedQty != null && product.ProductTMD.ProductTMDLimitedQty > 0) product.ProductLimitedQuantity = product.ProductTMD.ProductTMDLimitedQty.ToString();
}
private void SetNFPATags(tblMATProduct product)
{
if (product.tblProduct != null && product.tblProduct.tblProductNFPA != null)
{
foreach (var productNFPA in product.tblProduct.tblProductNFPA)
{
if (productNFPA.NFPATypeID == 1) product.ProductInflammabilityLevel = productNFPA.tblNFPAValue.NFPAValueCode;
if (productNFPA.NFPATypeID == 2) product.ProductToxicityLevel = productNFPA.tblNFPAValue.NFPAValueCode;
if (productNFPA.NFPATypeID == 3) product.ProductReactivityLevel = productNFPA.tblNFPAValue.NFPAValueCode;
}
if (product.ProductInflammabilityLevel == null) product.ProductInflammabilityLevel = "0";
if (product.ProductToxicityLevel == null) product.ProductToxicityLevel = "0";
if (product.ProductReactivityLevel == null) product.ProductReactivityLevel = "0";
}
}
请注意,除了使用之外,我还接受其他建议ForEachAsync()
。
提前致谢!
我没有尝试将其放入评论中,而是有一些问题和您应考虑的事项-也许您甚至可以在这里找到答案:
我想将其移入
ForEachAsync()
。
问:您是否有理由专门写“异步”?如果您不需要将其作为异步操作,那么就省掉它。
AllProducts = db.tblMATProduct
.Include(s => s.tblGrade)
.Include(s => s.tblMATProductState)
.Include(s => s.tblFormat)
.Include(s => s.tblProduct)
.ThenInclude(s => s.tblBatch)
.OrderBy(s => s.MATProductID)
.ToList();
问:在上面的“查询”中,您没有过滤或分页任何内容,这意味着该ToList()
调用使您的查询从该表中读取所有数据以及包括在所包含表中的所有数据。您说有24.000行,这意味着您有可能同时将很多数据加载到内存中。也许您的数据不是很复杂,这不是问题,但这是您打算做什么?
基本上,以下所有代码用于修改我的列表中的对象
Allproducts
问:这些修改是否全部用于更新数据库中的数据或仅用于在UI中显示?带的行product.ProductNumLotCount = "No. Lot (" + 0 + ")";
向我表明这是出于UI目的。
如果我的猜测是正确的,我建议您为此单独创建一些类/数据模型,而不要使用数据库模型来显示数据。即,因此您具有单独的数据访问模型和业务对象模型。这使您更轻松地仅出于需要模型的目的来设计模型。这样,您所说的修改就更好地称为从数据访问模型到业务对象模型的“映射”。
这将帮助我删除以下操作,这些操作由于不必要的foreach(使用LINQ构建列表,然后再次加载以修改其对象)而非常昂贵。
问:您为什么认为foreach
不需要循环?foreach
除了您的代码片段中的第一个循环外,所有循环都循环遍历产品属性中的列表,而不是AllProducts
列表本身。一个循环不能替代所有这些。
关于“使用LINQ构建列表,然后再次加载它以修改其对象”-我猜这里的意思是,您首先要创建列表,然后遍历它来修改对象。相反,您想要的是在创建列表之前修改对象,对吗?
为此,您可以使用LINQSelect
扩展方法。但是,由于IQueryable<tblMATProduct>.Select(...)
期望将表达式作为参数,因此需要使代码作为表达式工作,在这种情况下,这可能对您有些困难。无论如何,除非您有证明这会导致性能问题的证据,否则我不建议您花时间尝试对其进行优化,直到稍后。相反,我在这里指向我在第3点中的评论,并建议您将“修改”实现为数据对象之间的映射-将物理模型与业务逻辑分离可以帮助您避免严重的麻烦。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句