C# 带有DbContext多级包含()的AutoMapper ProjectTo
我需要在EF核心选择期间执行多级C# 带有DbContext多级包含()的AutoMapper ProjectTo,c#,.net-core,automapper,entity-framework-core-3.1,C#,.net Core,Automapper,Entity Framework Core 3.1,我需要在EF核心选择期间执行多级Include()查询。我将AutoMapper与ProjectTo()一起使用 我在mappingsExplicitExpansion()中指定了导航属性,这意味着导航属性不会自动填充,因为我希望能够多次执行同一查询并 一次Include()导航属性,但第二次忽略它 ProjectTo()方法具有参数,允许我将导航属性包含到选择中,但我需要执行多级包含。这可能吗?像这样的语法包括(e=>e.Collection.Select(sc=>sc.MyProperty)
Include()
查询。我将AutoMapper与ProjectTo()
一起使用
我在mappingsExplicitExpansion()
中指定了导航属性,这意味着导航属性不会自动填充,因为我希望能够多次执行同一查询并
一次Include()
导航属性,但第二次忽略它
ProjectTo()
方法具有参数,允许我将导航属性包含到选择中,但我需要执行多级包含。这可能吗?像这样的语法包括(e=>e.Collection.Select(sc=>sc.MyProperty))
在这种情况下不起作用
我试图对DbContext
使用Include()。然后对DbContext
使用Include()
,然后执行ProjectTo
,但在这种情况下,ProjectTo
会覆盖我的Include,并忽略它们
现在我不确定是否可以在映射中指定ProjectTo
,ExplicitExpansion()
,并使用多级包含?您尝试过吗
dbContext.Entities.ProjectTo(dest=>dest.Collection.Select(item=>item.MyProperty));
我尝试将Include()用于DbContext,然后执行ProjectTo,但在这种情况下,ProjectTo
会覆盖我的Include,并忽略它们。
此覆盖正在按预期工作
Select()
覆盖Include()
以下文件中明确提到了这一点:
如果更改查询,使其不再返回查询开始时的实体类型的实例,则会忽略include运算符
在下面的示例中,include操作符基于Blog
,但是Select
操作符用于更改查询以返回匿名类型。在这种情况下,include操作符无效
包括
Include()
指示EF在获取请求的结果集时加载一些相关实体。此行为添加到EF的默认加载行为中:
var people = db.People.ToList();
var peopleWithPets = db.People.Include(person => person.Pets).ToList();
通过添加Include()
,您基本上扩展了枚举集合时在引擎盖下发生的加载行为(在本例中,ToList()
)
选择
Select()
用您定义的新行为覆盖默认加载行为
var people = db.People.ToList();
var names = db.People.Select(person => person.Name).ToList();
当您调用Select()
时,实际上是指示EF不要执行其默认加载行为(可能需要也可能不需要额外的包含),而是完全加载您指定的内容(在本例中,person=>person.Name
)
ProjectTo()
是Select()
您可以将ProjectTo()
视为一种SelectFactory
,它根据Automapper中配置的tdestation
映射生成相应的Select
语句。在引擎盖下,EF仍然执行
Select()
,因此使用ProjectTo()
时,上述行为同样适用
如果要包括其他相关实体或其任何属性,则需要展开Automapper映射,而不是在查询中使用include
。如果映射包含其他字段,Automapper将相应地扩展其基础Select()
即使您能够使用
include
包含相关实体,但如果您从未将它们定义为映射,Automapper也会忽略它们。我尝试过,但这会导致结果中的集合为空。似乎不是有效的表达式。它现在是EF Core 5,而且这种方法有效。我清楚地知道,这种覆盖正在按预期工作。
所以,仍然,为什么AutoMapper打算为带有ExplicitExpansion
的字段支持include,但不应该支持第二级include。@Alexey:您可以使用适当的映射包含相关实体,但在同时使用ProjectTo()时,您不能使用include
来实现此目的
显式扩展需要Automapper自动尝试填充目标类型的每个属性,这可能会排除您显式映射相关实体的需要(即,如果映射可以自动完成),但它仍然不会改变您不应该使用Include()的事实
这里。我感到困惑的是,ProjectTo
支持membersToExpand
逻辑,但只有一个级别。@AlexeyKlipilin:只有一个级别听起来像是一个任意规则,但它很有意义,因为它特别防止循环引用成为无限循环。如果Company
拥有Company.Employees
和Employees
拥有Employees.Company
(即该关系的另一端),那么您将陷入一个无限循环,即实例化B实例化A实例化B实例化A实例化B实例化A。。。考虑到使用EF和导航属性实现Automapper的ProjectTo
的可能性很高,这样的循环引用几乎是不可避免的。但是Automapper可以使用通常的Include
方法轻松处理循环引用。您不需要Include
@卢西安巴加阿努好吧。。。我需要它,因为AutoMapper支持ProjectTo方法中的一级包含,所以它不支持第二级包含的包含。请仔细阅读文档。或者查看GitHub repo中的相关测试。