如何有效地加载嵌套的Entity Framework对象

时间:2011-09-01 17:45:35

标签: c# entity-framework-4

我正在尝试使用实体框架

将3深树加载到树视图控件中

类别,子类别和产品 在下面的代码类别是IQueryable<ProductCategory>,其中ProductCategory是EF4.0生成的对象(默认代码生成)

SubCategories是FK回到类别表(所以理论上我们可以进入任何深度,但数据域只有两个级别)

var container = categories.Where(c=>c.somecondition).Include("Subcategories.Products");
foreach (var cat in container) {
  addtoTree(cat);
  foreach (var sub in cat.SubCategories)
  {
     addtoTree(sub);
     foreach (var prod in sub.Products) addtoTree(prod);

  }
}

这仍然是为每个内循环迭代发出查询。我是否遗漏了EF配置中的某些内容(更改了上下文?)以阻止这种情况发生?或者是否有另一种编写此类代码的方法?

(作为一个可怕的黑客,我现在已经创建了一个SQL视图来平整信息,我迭代它来手工重建嵌套对象......讨厌,但速度很快!)

2 个答案:

答案 0 :(得分:2)

在循环之前尝试通过调用.ToList()来急切地执行查询:

var container = categories
    .Where(c => c.somecondition)
    .Include("Subcategories.Products")
    .ToList();

答案 1 :(得分:0)

在处理可能复杂的层次结构时,它可以帮助您提取所需数据的简化结构。这将避免需要急切加载,因为数据将加入到结果中,加载必要的内容,并且通常可以更好地利用数据库服务器端的索引。

例如,如果你想加载&#34;基本&#34;有关适合在树形结构中显示的类别,子类别和产品的详细信息:

var results = dbContext.Categories.Where(c=> /*some condition*/)
    .Select(c=> new {c.CategoryId, c.Name, SubCategories = 
        c.SubCategories.Select(sc=> new { sc.SubCategoryId, sc.Name, Products = sc.Products.Select(p=> new {p.ProductId, p.Name}) }) }).ToList();

当然,它可能看起来不是很漂亮,但是对于渴望加载表达式没有神奇的字符串,而EF生成的SQL通常会提高几个订单的效率。利用您在这些表格上通常需要的索引。

对于简单实体,您可以使用它来。通过子层次结构向下选择,但是当处理较重的实体时,您只需要一些关键细节,这样可以通过仅检索和传输来节省相当多的处理和网络带宽。你需要的数据。