实体框架 - 对象属性

时间:2011-03-18 18:13:44

标签: entity-framework

我正在尝试使用Entity Framework进行模型/数据访问,并遇到速度问题,希望有人可以提供帮助吗?

我一直在做的是使用带有默认代码生成器的EF图来生成描述将要保留的任何内容的部分类。然后我有部分类与方法和非持久属性。这些可能是简单的事情,如全名作为连接的名/姓,或从相关实体派生,例如总库存作为库存位数集合的总和。

访问相关实体的任何方法都有效,但似乎非常慢。这是一个特别慢的例子,需要大约6-7秒:

所涉实体的简要说明:

供应商 - >提供许多SupplierLines,每个都有成本价格 SupplierLine - >细分为StockLines StockLine - >有很多地点,每个地点都有数量

所以我试图添加一个方法来获取供应商的总库存价值,即mySupplier.StockValue(),这显然应该是每个供应商行及其库存行的总成本价格x总量。< / p>

我已将此作为供应商中的一项功能:

Public Function StockValue() As Decimal
        Return SupplierLines.
            Sum(Function(sul) sul.LastPrice * sul.StockLines.Sum(Function(skl) skl.Locations.Sum(Function(l) l.Quantity)))
    End Function

这会给出正确的结果,但需要永远这样做。

有关如何获得更好结果的任何想法?

  • 我想保留我的模型类persistence-ignorant
  • 我想保留所有逻辑编译检查
  • 我希望使用虚假数据源轻松地对所有内容进行单元测试
  • 我真的不想预先加载这些信息,因为并不总是需要

2 个答案:

答案 0 :(得分:1)

您的问题很可能是延迟加载。如果仅加载Supplier实体,则它不会加载其已验证的SupplierLine实例,并且它们会关联StockLine个实例及其相关的Location实例。如果确实如此(如果您在查询检索Include时没有Supplier),情况如下:

  1. SupplierLines. - 对数据库执行查询以获取当前供应商的所有行
  2. sul.StockLines. - 对每个供应商行执行单独查询以获取其库存行
  3. skl.Locations. - 对每个股票行执行单独查询以获取其位置
  4. 因此,根据您在这些集合中的数据量,您最终可能会在第一次调用StockValue时执行数十到数千个SQL查询。下次调用将很快,因为数据已经加载。

    如果您想避免它,您必须检索供应商及其所有实际数据:

    context.Supplier.Include("SupplierLines.StockLines.Locations").Where(...);
    

答案 1 :(得分:1)

我找到了一个扩展IEnumerable的Include()...方法,并使用它。它解决了性能问题,同时保持对上下文的无知。