实体框架6代码优先 - 嵌套实体计算非常慢

时间:2015-12-08 20:42:45

标签: c# sql entity-framework-6

从数据库中检索时,是否可以使用实体模型返回计算值。例如 -

public class PaymentCertificate : DBModelBase
{
    public PaymentCertificate()
    {
        ValuationItems = new Collection<ValuationItem>();
    }
    public virtual ICollection<ValuationItem> ValuationItems { get; set; }
}

public class ValuationItem: DBModelBase
{
    public virtual Cost Cost { get; set; }
    public decimal ValuationQuantity { get; set; }
}

public class Cost: DBModelBase
{
    public decimal Price { get; set; }
}

当我从数据库返回说几百个PaymentCertificate模型时,我想计算每个模型的总数,所以目前我正在使用一个循环,例如。

foreach (var cert in PaymentCertificateList)
{
    var total = PaymentCertificateList
        .Sum(x => x.ValuationItems.ValuationQuantity*x.ValuationItems.Cost.Price);
}

计算几百个支付证书时,这真的很慢,我相信这是因为嵌套实体的计算(使用automapper时甚至更慢)。从数据库返回证书对象时,如何“预加载”Total值?我认为这是将计算推送到数据库端的最佳选择。这可能吗?欢迎任何建议。

2 个答案:

答案 0 :(得分:0)

如果您延迟加载引用的表,它将在数据库中查询循环中的每个调用。您可以通过使用.Include来急切加载相关实体来避免这种情况。

https://msdn.microsoft.com/en-us/data/jj574232.aspx

除此之外,您还可以使用投影在初始查询中执行某些计算。我不确定这是否适用于您的情况,因为您没有发布任何初步查询。

看看你的模型你可以做这样的事情来获得所有的总数

var totals = DbContext.PaymentCertificates
                .Include("ValuationItems.Cost")
                .Select(c => new {
                    Total = c.ValuationItems.Sum(x => x.Cost.Price*x.ValuationQuantity)
                });

答案 1 :(得分:0)

您可以为每个人添加一个属性来为此返回:

 public class PaymentCertificate : DBModelBase
 {
     public PaymentCertificate()
     {
         ValuationItems = new Collection();
     }
     public virtual ICollection ValuationItems { get; set; }

     [NotMapped]
     public decimal Total { get {return ValuationItems.Sum(v => v.ValuationQuantity * v.Cost.Price); }; private set;}
 }

NotMapped属性表示EF会忽略它。