【问题标题】:Entity Framework slow with large datasets大型数据集的实体框架速度慢
【发布时间】:2011-12-21 19:07:19
【问题描述】:

我正在使用实体框架来检索大型数据集。

数据集集合有父子关系,需要同时带回父子信息。

我发现 EF 最初发送一个查询以获取父对象列表,然后遍历每个父对象并查询 DB 以获取子信息。

因此,如果我有 1000 个父对象,我最终会总共调用 1001 次数据库(每个父对象一次,加上获取父对象列表的原始查询)。

无论如何让EF查询这是一种更有效的方式?比如:

SELECT * FROM CHILD_OBJECT_TABLE WHERE PARENTID IN (LIST OF PARENT_IDS HERE)

【问题讨论】:

  • 您的孩子和父母都在一张桌子上吗?
  • 不,这是两个单独的表。子节点对父节点有一个外键。
  • 表中的行数是否比您尝试加载的行数多?还是要全部加载?

标签: sql performance entity-framework


【解决方案1】:

您是如何执行查询的?如果您使用延迟加载,您将体验到您描述的行为。相反,使用Include 函数指定特定导航属性(无论是相关实体还是集合)作为查询的一部分加载。简而言之,EF 将生成两种关系的扁平笛卡尔积,然后在实例化您的对象时将数据正确地重新膨胀为父->子关系。

例如,如果您的父类有一个名为“Children”的集合属性,您可以这样称呼它:

context.Parents.Include("Children").Where(p=> ...)

或者,如果您更喜欢查询语法而不是扩展方法语法...

from p in context.Parents.Include("Children")

where p ...

【讨论】:

    【解决方案2】:

    最简单的方法是,你可以在一个上下文中使用两个调用,所有调用都会被加载,作为 EF 无论如何都会映射关系,即使它们的加载方式不同,但是,应该先加载所有子节点,然后再加载父节点。

     // load children
     var children = context.ChildTypes.Where(
          x => x.Parent.SomeProperty == SomeValue );
    
     var parents = context.ParentTypes.Where(
          x => x.SomeProperty == SomeValue );
    

    这将正确加载所有内容,并注意在两个查询中都应用了条件,不需要 IN 操作,因为 EF 将映射 ParentType 的条件以正确加入并加载相关条目。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-27
      • 1970-01-01
      • 1970-01-01
      • 2013-01-30
      • 1970-01-01
      • 2011-07-24
      • 1970-01-01
      • 2021-05-16
      相关资源
      最近更新 更多