Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何有效地加载嵌套实体框架对象_C#_Entity Framework 4 - Fatal编程技术网

C# 如何有效地加载嵌套实体框架对象

C# 如何有效地加载嵌套实体框架对象,c#,entity-framework-4,C#,Entity Framework 4,我正在尝试使用实体框架将一个3层的树加载到treeview控件中 类别、子类别和产品 在下面的代码中,类别是一个IQueryable,其中ProductCategory是一个EF4.0生成的对象(默认代码生成) 子类别是返回到categories表的FK(因此理论上我们可以访问任何深度,但data domain将只有两个级别) 这仍然是为每个内部循环迭代发出查询。我是否在EF配置中遗漏了阻止这种情况发生的内容(对上下文的更改?)?或者有没有其他方法来编写这种代码 (作为一个可怕的黑客,我现在已经

我正在尝试使用实体框架将一个3层的树加载到treeview控件中

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

子类别是返回到categories表的FK(因此理论上我们可以访问任何深度,但data domain将只有两个级别)

这仍然是为每个内部循环迭代发出查询。我是否在EF配置中遗漏了阻止这种情况发生的内容(对上下文的更改?)?或者有没有其他方法来编写这种代码


(作为一个可怕的黑客,我现在已经创建了一个SQL视图,它可以将信息展平,并且我会反复使用它来手动重新构建嵌套对象……很讨厌,但是很快!)

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

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

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

例如,如果要加载适合在树结构中显示的类别、子类别和产品的“基本”详细信息:

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通常效率会高出几个数量级&利用您通常希望在这些表上使用的索引


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

我添加了收费表,但没有任何效果:我编辑了问题的更多细节,即类别和子类别是同一个表……可能是这样的相关的(本来应该放进去的)事实上你的例子在我发布的简化例子上当然可以完美地工作…我将尝试找出我的真实世界例子中的实际不同之处!发现了额外的错误-如果您的代码(在我的示例中隐藏在addtoTree(sub))试图引用备份树,您需要将其包含在include语句中-即include(“Subcategories.Products.Subcategories”)(在本例中为多个关系)
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();