计算属性中相关表的性能

时间:2014-03-13 02:25:44

标签: c# sql-server entity-framework

想看看是否有更好的方法来做到这一点。

我首先使用数据库,并有一个名为Items的表。下面是我在部分类上指定的计算属性,用于扩展它,使用相关表来派生结果。这在技术上工作正常。我喜欢使用它的简易性,所有这些业务逻辑都在域中定义一次,并且您可以使用复杂的代码来获得结果。

我关注的唯一问题是性能,当您撤回多个记录时。使用SQL事件探查器,我可以看到,如果你撤回50行项目,它将执行一个额外的查询来检索工作订单明细,在这种情况下,50次!不知道为什么它没有进行连接而不是进行50次额外读取???我有多个这样的计算属性出现在多个表中,每个表每行显式读取=慢!

从Item表中撤回50行的结果是,SQL Profiler指示的数据库中有2,735个读取!我对SQL Profiler并不熟悉,所以也许我误解了一些东西,但我知道它正在进行大量的数据库读取。

  1. 为什么不进行连接而不是对Item中每行的相关表进行显式读取?
  2. 什么是"最佳实践"完成这个?还有更好的方法吗?
  3. [Display(Name = "Qty Allocated")]
    public decimal QtyAllocated
    {
        get
        {
            if (this.TrackInventory)
            {
                var inProcessNonRemnantWorkOrderDetails = this.WorkOrderDetails.Where(wod =>
                        new[] 
                        {
                            (int)WorkOrderStatus.Created, 
                            (int)WorkOrderStatus.Released,
                            (int)WorkOrderStatus.InProcess
                        }.Contains(wod.WorkOrderHeader.StatusId)
                        && wod.EstimatedQuantity >= 1 //Don't count remnants as allocated
                        );
    
                var inProcessRemnantWorkOrderDetails = this.WorkOrderDetails.Where(wod =>
                        new[] 
                        {
                            (int)WorkOrderStatus.Created, 
                            (int)WorkOrderStatus.Released,
                            (int)WorkOrderStatus.InProcess
                        }.Contains(wod.WorkOrderHeader.StatusId)
                        && wod.EstimatedQuantity > 0 && wod.EstimatedQuantity < 1 //gets just remnants
                        );
    
                decimal qtyAllocated = 
                    this.WorkOrderDetails == null 
                    ? 0
                    : inProcessNonRemnantWorkOrderDetails.Sum(a => (a.EstimatedQuantity - a.ActualQuantity));
    
                if (qtyAllocated == 0 && inProcessRemnantWorkOrderDetails.Any())
                {
                    qtyAllocated = 0.1M;
                }
                return qtyAllocated;
            }
            else
            {
                return 0;
            }
        }
    }
    

1 个答案:

答案 0 :(得分:0)

阿隆是对的。当我eager load the related entities在我的查询中使用Include()方法时,数据库只有一次命中。