简体   繁体   English

使用 ThenInclude() 的结果,而不是再次从 Include() 开始。 实体框架核心 5

[英]Using the result of ThenInclude() rather than starting at Include() again. Entity Framework Core 5

I am pretty new to EF Core, so if this question seems obvious, go easy on me :)我对 EF Core 很陌生,所以如果这个问题看起来很明显,请放轻松:)

As the title mentions, I would like a way to simplify queries in EF core, so that I don't have to reset at the top of my query with the Include() method.正如标题所提到的,我想要一种方法来简化 EF 核心中的查询,这样我就不必在查询顶部使用Include()方法进行重置。

Here is a sample of what I'm dealing with/trying to get rid of.这是我正在处理/试图摆脱的示例。

var result = await _dbContext.Zoo
                    .AsNoTracking()
                    .Include(zoo => zoo.Animal)
                        .ThenInclude(animal => animal.Cow)
                    .Include(zoo => zoo.Animal)
                        .ThenInclude(animal.Dog)
                    .Include(zoo => zoo.Animal)
                        .ThenInclude(animal.Goat)
                    .FirstOrDefaultAsync(zoo => zoo.Name = "Cool Pets");

This works, and based on the question answer provided by Poke (where I got the inspiration for the example above), this is the way that this type of query needs to be handled.这是可行的,并且基于Poke提供的问题答案(我从上面的示例中获得灵感),这是需要处理此类查询的方式。

From another question answered by Serge , a way to counter this is to use strings and other ways like so:Serge回答的另一个问题中,解决此问题的一种方法是使用字符串和其他方式,例如:

dbcontext.a.Include(x => x.b)
            .ThenInclude(x => x.c)
             .Include("b.d")

-------------------------
OR
-------------------------

dbcontext.a.Include(x => x.b)
            .ThenInclude(x => x.c)
             .Include(x => x.b.d)

So my question is, which approach to this type of query, if either, is best for readability and efficiency?所以我的问题是,这种查询的哪种方法(如果有的话)最适合可读性和效率?

First of all, you don't need to be inspired by SO answers since all this is very well documented in the Eager Loading of Related Data section of the official EF Core documentation, and in particular with lot of examples in Including multiple levels subsection (even though the string overload which was added later is not included there).首先,您不需要受到 SO 答案的启发,因为所有这些都在官方 EF Core 文档的Eager Loading of Related Data部分中得到了很好的记录,特别是在包括多个级别小节中的许多示例(即使后面添加的字符串重载不包括在内)。

But to answer your concrete questions.但是要回答您的具体问题。

Using the result of ThenInclude() rather than starting at Include() again使用 ThenInclude() 的结果,而不是再次从 Include() 开始

This is not possible, because "restarting" the include path this way is by design, and in general is the way Include -> ThenInclude -> ThenInclude ... pattern works这是不可能的,因为以这种方式“重新启动”包含路径是设计使然,并且通常是Include -> ThenInclude -> ThenInclude ... 模式的工作方式

As the title mentions, I would like a way to simplify queries in EF core, so that I don't have to reset at the top of my query with the Include() method正如标题所提到的,我想要一种方法来简化 EF 核心中的查询,这样我就不必在查询顶部使用Include()方法进行重置

and

So my question is, which approach to this type of query, if either, is best for readability and efficiency?所以我的问题是,这种查询的哪种方法(如果有的话)最适合可读性和效率?

Readability is subjective, so it's up to you.可读性是主观的,所以这取决于你。 Efficiency - it doesn't matter (thus no need of "simplification" or "optimization") because all these methods are equivalent and produce one and the same query and result(if something needs optimization, it is how many things you include, not how you include them in the query result).效率 - 没关系(因此不需要“简化”或“优化”),因为所有这些方法都是等价的,并且产生一个相同的查询和结果(如果需要优化,那就是你包含了多少东西,而不是如何将它们包含在查询结果中)。

All you need to realize is that你需要意识到的是

(1) all these methods are alternative ways of expressing include paths . (1) 所有这些方法都是表达包含路径的替代方式。 ThenInclude is specifically for solving C# syntax problem with including property of an element of a collection, ie while you can write Include(a => aBC) in case B is reference type navigation, you can't write Include(a => a.Bs.C) where Bs is collection of B having property C . ThenInclude专门用于解决包含集合元素属性的 C# 语法问题,即当B是引用类型导航时您可以编写Include(a => aBC) ,但不能编写Include(a => a.Bs.C)其中Bs是具有属性CB的集合。 In that case you could use the string overload Include("Bs.C") , but the problem with strings in general is that they are error prone and you loose type safety provided by expressions.在这种情况下,您可以使用string重载Include("Bs.C") ,但通常字符串的问题是它们容易出错并且您失去了表达式提供的类型安全性。 "Classic" Entity Framework (EF6) solves the collection include syntax problem with standard LINQ Select , ie Include(a => a.Bs.Select(b => bC)) , however it looks a bit unnatural, hence EF Core introduced the "more intuitive" ThenInclude . “经典”实体框架 (EF6) 使用标准 LINQ Select解决了集合包含语法问题,即Include(a => a.Bs.Select(b => bC)) ,但是它看起来有点不自然,因此 EF Core 引入了“更直观” ThenInclude

(2) Only unique paths are included in the generated query. (2) 生成的查询中只包含唯一路径。 In other words, repeating Include(zoo => zoo.Animal ) doesn't mean it will be included many times.换句话说,重复Include(zoo => zoo.Animal ) 并不意味着它会被包含很多次。 No, it will be included only once.不,它只会包含一次。 Same for sub paths you have to repeat in order to ThenInclude another property.对于必须重复的子路径也是如此,以便ThenInclude另一个属性。

(3) Including a path automatically includes all the levels, ie (3) 包含路径自动包含所有层级,即

Include(a => a.B).ThenInclude(b => b.C).ThenInclude(c => c.D)

and

Include(a => a.B.C.D)

do one and the same.做同样的事情。


With all that being said, which one method to use for particular scenario is simply a matter of personal taste.话虽如此,对于特定场景使用哪种方法只是个人喜好问题。 I personally use the compact expression form where possible (basically until you hit a collection), ThenInclude otherwise, and avoid string overload due to the obvious maintenance (not functional or efficiency) drawbacks, even though the later can eventually be solved with interpolated strings and nameof operators.我个人尽可能使用紧凑的表达式形式(基本上直到你点击一个集合),否则使用ThenInclude ,并避免由于明显的维护(不是功能或效率)缺点而导致的string过载,即使后者最终可以通过插值字符串和nameof商名称。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Entity Framework Core Include/ThenInclude 获取数据 - Entity Framework Core Include/ThenInclude to get the data Entity Framework Core 6 中的 Simplify.Include 和.ThenInclude 调用 - Simplify .Include and .ThenInclude calls in Entity Framework Core 6 Entity Framework Core 如何在不使用 Include().ThenInclude() 的情况下从模型中从多对多列出一对多 - Entity Framework Core how to list one to many from many to many from a model without using Include().ThenInclude() .ThenInclude 用于 Entity Framework Core 2 中的子实体 - .ThenInclude for sub entity in Entity Framework Core 2 在实体框架中使用带有条件的 ThenInclude - Using ThenInclude with condition in Entity Framework 然后在实体框架核心中包含显式加载? - ThenInclude for Explicit Loading in Entity Framework core? 网络核心:实体框架然后包含在Projection Select中 - Net Core: Entity Framework ThenInclude with Projection Select Entity Framework Core - 我可以直接查询子属性中的列表/对象,避免多次重复包含/然后包含吗? - Entity Framework Core - Can I query lists/objects in child property directly avoiding multiple repeating Include/ThenInclude? 如何使用.net-core和Entity Framework Core和Identity从thenInclude中获取特定列? - How do i get specific columns from a thenInclude using .net-core and Entity Framework Core and Identity? 使用 Include 与 ThenInclude - Using Include vs ThenInclude
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM