实体框架核心ForEachAsync

兰迪·奎克斯

我目前正在尝试优化我的应用程序。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()

提前致谢!

Xerillio

我没有尝试将其放入评论中,而是有一些问题和您应考虑的事项-也许您甚至可以在这里找到答案:

  1. 我想将其移入ForEachAsync()

问:您是否有理由专门写“异步”?如果您不需要将其作为异步操作,那么就省掉它。

  1. 当前,这是从数据库中读取数据的方式:
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行,这意味着您有可能同时将很多数据加载到内存中。也许您的数据不是很复杂,这不是问题,但这是您打算做什么?

  1. 基本上,以下所有代码用于修改我的列表中的对象 Allproducts

问:这些修改是否全部用于更新数据库中的数据或仅用于在UI中显示?带的行product.ProductNumLotCount = "No. Lot (" + 0 + ")";向我表明这是出于UI目的。

如果我的猜测是正确的,我建议您为此单独创建一些类/数据模型,而不要使用数据库模型来显示数据。即,因此您具有单独的数据访问模型和业务对象模型。这使您更轻松地仅出于需要模型的目的来设计模型。这样,您所说的修改就更好地称为从数据访问模型到业务对象模型的“映射”。

  1. 这将帮助我删除以下操作,这些操作由于不必要的foreach(使用LINQ构建列表,然后再次加载以修改其对象)而非常昂贵。

问:您为什么认为foreach不需要循环?foreach除了您的代码片段中的第一个循环外,所有循环都循环遍历产品属性中的列表,而不是AllProducts列表本身。一个循环不能替代所有这些。

关于“使用LINQ构建列表,然后再次加载它以修改其对象”-我猜这里的意思是,您首先要创建列表,然后遍历它来修改对象。相反,您想要的是在创建列表之前修改对象,对吗?

为此,您可以使用LINQSelect扩展方法。但是,由于IQueryable<tblMATProduct>.Select(...)期望将表达式作为参数,因此需要使代码作为表达式工作,在这种情况下,这可能对您有些困难。无论如何,除非您有证明这会导致性能问题的证据,否则我不建议您花时间尝试对其进行优化,直到稍后相反,我在这里指向我在第3点中的评论,并建议您将“修改”实现为数据对象之间的映射-将物理模型与业务逻辑分离可以帮助您避免严重的麻烦。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

实体框架核心收益

来自分类Dev

实体框架核心.include()问题

来自分类Dev

实体框架核心的反向引擎

来自分类Dev

实体框架核心级联删除

来自分类Dev

实体框架(核心)-级联删除

来自分类Dev

实体框架的核心所在

来自分类Dev

实体框架核心.include()问题

来自分类Dev

渴望加载实体框架核心

来自分类Dev

实体框架核心加入并包含内部实体

来自分类Dev

使用实体框架或实体框架核心删除父子关系

来自分类Dev

检索由实体框架核心生成的SQL

来自分类Dev

带有实体框架核心的NoSQL

来自分类Dev

实体框架核心多对多未插入

来自分类Dev

实体框架核心不包含“包含”的定义

来自分类Dev

与实体框架核心的左外连接

来自分类Dev

实体框架核心-更改“ __EFMigrationsHistory”表的架构

来自分类Dev

实体框架核心(7)批量更新

来自分类Dev

实体框架核心:如何添加复合对象?

来自分类Dev

强类型的ID在实体框架的核心

来自分类Dev

实体框架核心3模拟PARTITION BY

来自分类Dev

实体框架核心组按日期范围

来自分类Dev

在实体框架核心上禁用AutoDetectChanges

来自分类Dev

实体框架核心不会更新ICollection

来自分类Dev

实体框架核心无钥匙导航问题

来自分类Dev

实体框架核心组截止日期

来自分类Dev

实体框架核心导致无法加载netstandard

来自分类Dev

实体框架核心能否返回视图模型

来自分类Dev

实体框架核心3.1.1多级继承

来自分类Dev

实体框架核心级联删除错误