2014-03-13 197 views
0

因此,这个问题很可笑,所以我们来看代码。什么是linq2entities相当于以下SQL的,因为实体的样子(表):Linq2Entities针对父母/子女关系的等效查询,与所有父母和子女,筛选/订购子女

Parent 
--- 
parent_id 
parent_field1 

Child 
-- 
child_id 
parent_id 
child_field1 
child_field2 

的SQL:

select p.*, c.* 
from parent p 
inner join p on 
    p.parent_id = child.parent_id 
where 
    c.child_field1 = some_appropriate_value 
order by 
    p.parent_field1 
    c.child_field2 

L2E让我们这样做条.include()和这似乎是适当的地方坚持孩子的排序和筛选,但include方法不接受一个表达式(为什么不呢?)。所以,我猜这是不能立即完成的,因为这是很多文章的说法,但它们很老,我想知道EF6是否可能。

此外,我没有访问上下文,所以我需要lambda语法版本。

我要寻找一个结果对象的层次结构,看起来像:

Parent1 
    | 
    +-- ChildrenOfParent1 
    | 
Parent2 
    | 
    +-- ChildrenOfParent2 

等等。该列表最终将成为IEnumerable。如果迭代了该列表,他们可以获取该列表中每个父代的.Children属性。

理想(我是在做梦这里,我想),就是整体大小结果列表的可能是有限的。例如,如果有三个父母,每个有10个孩子,总共有33个(30个孩子+ 3个父母)实体,我可以将总列表限制为某个任意值,例如13,在这种情况下,这会限制结果集与第一个父母及其所有孩子,第二个父母仅与其子女中的一个(共13个实体)。我猜所有这些都必须在代码中手动完成,这是令人失望的,因为它可以在SQL中轻松完成。

回答

0

当您从db使用entityframewrok获取查询来提取父母时,会在单个查询中提取父代的字段。现在你有一个结果集是这样的:

var parentsQuery = db.Parents.ToList(); 

那么,如果你有对父foreign keyentityframework对父母产生了navigation property来访问correspondingentity(例如Child表)。

在这种情况下

,当你使用这个navigation propertyparent entities这已经被取出,拿到childsentityframework创建到sql server每个父另一个连接。

例如如果parentsQuery计数15,通过下面的查询entityframework创建15另一个连接,并得到15另一query

var Childs = parentsQuery.SelectMany(u => u.NavigationProperty_Childs).ToList(); 
在这些情况下,您可以使用 include防止额外的连接,以获取所有 childs

与其parent,当你试图让父母在单个查询中,像这样:

var ParentIncludeChildsQuery = db.Parents.Include("Childs").ToList(); 

然后按照Queryentityframework不会创建任何连接,不会再得到任何查询:

var Childs = ParentIncludeChildsQuery.SelectMany(u => u.NavigationProperty_Childs).ToList(); 

,但是,你不能创造任何条件和使用限制包括,您可以检查任何约束或条件后,包括使用WhereJoinContains等等,像这样:

var Childs = ParentIncludeChildsQuery.SelectMany(u => u.NavigationProperty_Childs 
    .Where(t => t.child_field1 = some_appropriate_value)).ToList(); 

但此查询,所有的孩子都被提取从database是前

更好的方式来acheieve相当于SQL查询:

 var query = parent.Join(child, 
       p => p.ID 
       c => c.ParentID 
       (p, c) => new { Parent = p, Child = c }) 
      .Where(u => u.Child.child_field1 == some_appropriate_value) 
      .OrderBy(u => u.Parent.parent_field1) 
      .ThenBy(u => u.Child.child_field2) 
      .ToList(); 
+0

如果我正确地读这篇文章,这将创造两个对象,父和子,并且该列表将只包含两个项目。这不是我想要的。我希望所有的父母对象,与他们的子女财产与与父母关联的孩子保持水分。 –

+0

这相当于你的'sql',并生成一个扁平列表,如果你想要分层结构,需要'groupby',检查我的新帖子 –

0
根据您的评论

,这是你想要什么:

var query = parent.Join(child, 
      p => p.ID, 
      c => c.ParentID, 
      (p, c) => new { Parent = p, Child = c }) 
     .Where(u => u.Child.child_field1 == some_appropriate_value) 
     .GroupBy(u => u.Parent) 
     .Select(u => new { 

      Parent = u.Key, 
      Childs = u.OrderBy(t => t.Child.child_field2).AsEnumerable() 
     }) 
     .OrderBy(u => u.Parent.parent_field1) 
     .ToList();