实体框架6延迟加载和查询导航属性

时间:2014-11-26 18:57:02

标签: entity-framework entity-framework-6

触发警告:我以前的NHibernate用户切换到EF。

刚刚遇到我对Entity Framework 6的第一次重大失望。在this abstract base class中,我拥有帐户的基本功能。

帐户包含一系列交易。为了确定账户的可用余额,我只需从总存款中减去总费用和未解除的保留金。这是与所有类型的帐户相关的纯商业逻辑。

为了获得总金额,我有一些属性按类型过滤帐户的交易,并对交易金额求和。有关我尝试执行此操作的几种方法的示例,请参阅TotalDepositAmount

我在EF中使用Lazy Loading,我期望EF做的是向数据库发出查询以获得存款交易的总和值。相反,EF获取帐户的所有事务并将它们加载到内存中,然后linq过滤它们。 WTF。

我只发现了这个问题,因为我在我的示例应用程序中进行了一些性能测试,并将30k个事务(完全可能的数量)抽入帐户。试图ToString我的帐户现在基本上崩溃了应用程序...

在挖掘之后,我发现查询导航属性的唯一方法是在获取父级或访问实体内的dbcontext时执行此操作..因此该属性看起来像这样..

public decimal TotalDepositAmount
{
    get
    {
        return context.Entry(this).Reference("Transactions").Query()
            .OfType<Deposit>().Sum(d => d.Amount);
    }
}

但是,当然,我无法访问我的实体中的上下文,并且它会完全污染我的实体的纯度......

所以,EF专家。我错过了什么如何实现我的目标是拥有纯域实体。我可以使用哪些工作或模式?

1 个答案:

答案 0 :(得分:0)

这假设你的基类Transactions有一个属性是存款列表

context.Transactions.Where(x => x.Deposit.Count > 1).Sum(d => d.Amount);

我使用

测试了这个
db.Database.Log = s => System.Diagnostics.Debug.WriteLine($"SQL: {s}");

并将其放在上面的行之前。如果查看输出,您应该看到事务受子选择中的where子句的限制。