所以这个问题太长了,所以让我们去看看代码吧。给定的实体(表格)如下所示,linq2entities等效于以下Sql:
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 :(得分:1)
当您使用db
从entityframewrok
获取查询以获取父项时,将在单个查询中提取父项的字段。现在你有这样的结果集:
var parentsQuery = db.Parents.ToList();
然后,如果您在父级上有foreign key
,则entityframework
会在父级上创建一个navigation property
来访问corresponding
entity
(例如{{1}表)。
在这种情况下,当您使用已经提取的Child
navigation property
时,parent entities
,childs
创建另一个与entityframework
的连接每个父母。
例如,如果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();
,Query
没有创建任何连接,也没有再次获得任何查询:
entityframework
但是,您无法使用include创建任何条件和约束,您可以在使用var Childs = ParentIncludeChildsQuery.SelectMany(u => u.NavigationProperty_Childs).ToList();
,Where
,Join
之后检查任何约束或条件,等等,像这样:
Contains
但是通过此查询,所有孩子都是在var Childs = ParentIncludeChildsQuery.SelectMany(u => u.NavigationProperty_Childs
.Where(t => t.child_field1 = some_appropriate_value)).ToList();
之前提取的
获取等效sql查询的更好方法是:
database
答案 1 :(得分: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();