使用 ThenInclude() 的结果而不是再次从 Include() 开始。 Entity Framework核心5
Using the result of ThenInclude() rather than starting at Include() again. Entity Framework Core 5
我是 EF Core 的新手,所以如果这个问题看起来很明显,请放轻松 :)
如标题所述,我想要一种方法来简化 EF 核心中的查询,这样我就不必使用 Include()
方法在查询的顶部进行重置。
这是我要处理的with/trying要摆脱的示例。
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");
这行得通,并且根据 提供的问题答案(我从中获得了上述示例的灵感),这就是此类查询需要处理的方式。
根据 回答的另一个问题,解决这个问题的方法是使用字符串和其他方式,例如:
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 答案的启发,因为所有这些都在 Eager Loading of Related Data section of the official EF Core documentation, and in particular with lot of examples in Including multiple levels 小节中有很好的记录(即使后来添加的字符串重载不包括在那里) .
但要回答你的具体问题。
Using the result of ThenInclude() rather than starting at Include() again
这是不可能的,因为以这种方式“重新启动”包含路径是设计使然,通常是 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
和
So my question is, which approach to this type of query, if either, is best for readability and efficiency?
可读性是主观的,因此取决于您。效率 - 这无关紧要(因此不需要“简化”或“优化”),因为所有这些方法都是 等效的 并产生一个相同的查询和结果(如果需要优化,它是您包含的 很多 事物的数量,而不是您将它们包含在查询结果中的方式。
你需要意识到的是
(1) 所有这些方法都是表达 include paths 的替代方法。 ThenInclude
专门用于解决包含集合元素的 属性 的 C# 语法问题,即虽然您可以编写 Include(a => a.B.C)
以防 B
是引用类型导航,但您可以不要写 Include(a => a.Bs.C)
,其中 Bs
是具有 属性 C
的 B
的集合。在那种情况下,您可以使用 string
重载 Include("Bs.C")
,但字符串的一般问题是它们容易出错,并且您会失去表达式提供的类型安全性。 “经典”Entity Framework (EF6) 解决了集合包含标准 LINQ Select
的语法问题,即 Include(a => a.Bs.Select(b => b.C))
,但它看起来有点不自然,因此 EF Core 引入了“更直观”ThenInclude
.
(2) 生成的查询中仅包含唯一路径。也就是说,重复 Include(zoo => zoo.Animal
) 并不意味着它会被多次包含。不,它只会包含一次。与子路径相同,您必须重复才能 ThenInclude
另一个 属性.
(3)包含路径自动包含所有级别,即
Include(a => a.B).ThenInclude(b => b.C).ThenInclude(c => c.D)
和
Include(a => a.B.C.D)
照样做。
话虽如此,针对特定场景使用哪种方法只是个人品味的问题。我个人尽可能使用紧凑的表达式形式(基本上直到你碰到一个集合),否则 ThenInclude
,并避免 string
由于明显的维护(不是功能或效率)缺点而过载,即使后来最终可以用内插字符串和 nameof
运算符来解决。
我是 EF Core 的新手,所以如果这个问题看起来很明显,请放轻松 :)
如标题所述,我想要一种方法来简化 EF 核心中的查询,这样我就不必使用 Include()
方法在查询的顶部进行重置。
这是我要处理的with/trying要摆脱的示例。
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");
这行得通,并且根据
根据
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 答案的启发,因为所有这些都在 Eager Loading of Related Data section of the official EF Core documentation, and in particular with lot of examples in Including multiple levels 小节中有很好的记录(即使后来添加的字符串重载不包括在那里) .
但要回答你的具体问题。
Using the result of ThenInclude() rather than starting at Include() again
这是不可能的,因为以这种方式“重新启动”包含路径是设计使然,通常是 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
和
So my question is, which approach to this type of query, if either, is best for readability and efficiency?
可读性是主观的,因此取决于您。效率 - 这无关紧要(因此不需要“简化”或“优化”),因为所有这些方法都是 等效的 并产生一个相同的查询和结果(如果需要优化,它是您包含的 很多 事物的数量,而不是您将它们包含在查询结果中的方式。
你需要意识到的是
(1) 所有这些方法都是表达 include paths 的替代方法。 ThenInclude
专门用于解决包含集合元素的 属性 的 C# 语法问题,即虽然您可以编写 Include(a => a.B.C)
以防 B
是引用类型导航,但您可以不要写 Include(a => a.Bs.C)
,其中 Bs
是具有 属性 C
的 B
的集合。在那种情况下,您可以使用 string
重载 Include("Bs.C")
,但字符串的一般问题是它们容易出错,并且您会失去表达式提供的类型安全性。 “经典”Entity Framework (EF6) 解决了集合包含标准 LINQ Select
的语法问题,即 Include(a => a.Bs.Select(b => b.C))
,但它看起来有点不自然,因此 EF Core 引入了“更直观”ThenInclude
.
(2) 生成的查询中仅包含唯一路径。也就是说,重复 Include(zoo => zoo.Animal
) 并不意味着它会被多次包含。不,它只会包含一次。与子路径相同,您必须重复才能 ThenInclude
另一个 属性.
(3)包含路径自动包含所有级别,即
Include(a => a.B).ThenInclude(b => b.C).ThenInclude(c => c.D)
和
Include(a => a.B.C.D)
照样做。
话虽如此,针对特定场景使用哪种方法只是个人品味的问题。我个人尽可能使用紧凑的表达式形式(基本上直到你碰到一个集合),否则 ThenInclude
,并避免 string
由于明显的维护(不是功能或效率)缺点而过载,即使后来最终可以用内插字符串和 nameof
运算符来解决。