且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Linq2Entities等效查询父母/子女关系,与所有父母和子女,过滤/订购子女

更新时间:2022-01-29 01:03:15

当您从db使用entityframewrok获取父项的查询时,将在单个查询中获取父项的字段.现在您得到了这样的结果集:

when you get a query from db using entityframewrok to fetch parents, parent's fields are fetched in single query. now you have a result set like this:

var parentsQuery = db.Parents.ToList();

然后,如果在父级上有foreign key,则entityframework在父级上创建navigation property可以访问corresponding entity(例如Child表).

then, if you have a foreign key on parent, entityframework creates a navigation property on parent to access to corresponding entity (for example Child table).

在这种情况下,当您使用已经获取的parent entities中的navigation property来获取childs时,entityframework将为每个父级创建与sql server的另一个连接.

in this case, when you use this navigation property from parent entities which already have been fetched, to get childs, entityframework creates another connection to sql server per parent.

例如,如果parentsQuery的计数为15,则通过以下查询entityframework创建15另一个连接,并获得15另一个query:

for example if count of parentsQueryis 15, by following query entityframework creates 15 another connection, and get 15 another query:

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

在这种情况下,当您试图在单个查询中获取父项时,可以使用include来防止额外的连接获取带有parent的所有childs,例如:

in these cases you can use include to prevent extra connections to fetch all childs with its parent, when you are trying to get parents in single query, like this:

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

然后按照Query的操作,entityframework不会创建任何连接,也不会再次获得任何查询:

then by following Query, entityframework doesn't create any connection and doesn't get any query again :

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

但是,您不能使用include创建任何条件和约束,可以使用WhereJoinContains等在包含之后检查任何约束或条件,如下所示:

but, you can't create any condition and constraint using include, you can check any constraint or conditions after include using Where, Join, Contains and so forth, like this:

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

,但通过此查询,之前已从database提取了所有子对象

but by this query, all child have been fetched from database before

实现等效sql查询的更好方法是:

the better way to acheieve equivalent sql query is :

     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();