我正在尝试使用实体框架
将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视图来平整信息,我迭代它来手工重建嵌套对象......讨厌,但速度很快!)
答案 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通常会提高几个订单的效率。利用您在这些表格上通常需要的索引。
对于简单实体,您可以使用它来。通过子层次结构向下选择,但是当处理较重的实体时,您只需要一些关键细节,这样可以通过仅检索和传输来节省相当多的处理和网络带宽。你需要的数据。