带有 DbContext 多级 Include() 的 AutoMapper ProjectTo
AutoMapper ProjectTo with DbContext multi level Include()
我需要在 EF Core select 期间执行多级 Include()
查询。我将 AutoMapper 与 ProjectTo<>()
一起使用。
我在映射中指定 ExplicitExpansion()
这意味着导航属性不会自动填充,因为我希望有可能多次执行相同的查询并且
一次 Include()
导航 属性 但第二次忽略它。
ProjectTo<>()
方法具有允许我将导航属性包含到我的 select 中的参数,但我需要执行多级包含。这可能吗? Include(e => e.Collection.Select(sc => sc.MyProperty))
这样的语法在这种情况下不起作用。
我尝试对 DbContext
使用 Include().ThenInclude()
,然后执行 ProjectTo
,但在那种情况下 ProjectTo
覆盖了我的包含,它们被忽略了。
现在我不确定是否可以在映射中指定 ProjectTo
、ExplicitExpansion()
并具有多级包含?
你尝试了吗?
dbContext.Entities.ProjectTo<EntityDto>(dest => dest.Collection.Select(item => item.MyProperty));
I tried to use Include().ThenInclude() for DbContext and then perform ProjectTo, but in that case ProjectTo
overrides my includes and they are ignored.
此覆盖按预期工作。
Select()
覆盖 Include()
EF documentation中明确提到了这一点:
If you change the query so that it no longer returns instances of the entity type that the query began with, then the include operators are ignored.
In the following example, the include operators are based on the Blog
, but then the Select
operator is used to change the query to return an anonymous type. In this case, the include operators have no effect.
包括
Include()
指示 EF 在获取请求的结果集时加载一些相关实体。此行为已添加到 EF 的默认加载行为中:
var people = db.People.ToList();
var peopleWithPets = db.People.Include(person => person.Pets).ToList();
通过添加 Include()
,您实质上扩展了枚举集合时发生在引擎盖下的加载行为(在本例中为 ToList()
)。
Select
Select()
用您定义的新行为覆盖默认加载行为。
var people = db.People.ToList();
var names = db.People.Select(person => person.Name).ToList();
当您调用 Select()
时,您实质上是指示 EF 不 执行其默认加载行为(这可能需要也可能不需要额外的包含),而是加载 完全您指定的内容(在本例中,person => person.Name
)。
ProjectTo<>()
是 Select()
的包装
您可以将 ProjectTo<TDestination>()
视为一种 SelectFactory
,它根据在 Automapper 中配置的 TDestination
映射生成适当的 Select
语句。
在幕后,EF 仍然执行 Select()
,因此在使用 ProjectTo<>()
.
时,上述行为同样适用
如果您想包含其他相关实体或其任何属性,您需要扩展 Automapper 映射,而不是在查询中使用 Include
。如果您的映射包含其他字段,Automapper 将相应地扩展其底层 Select()
。
即使您能够使用 Include
包含相关实体,但如果您从未将它们定义为映射,Automapper 仍会忽略它们。
我需要在 EF Core select 期间执行多级 Include()
查询。我将 AutoMapper 与 ProjectTo<>()
一起使用。
我在映射中指定 ExplicitExpansion()
这意味着导航属性不会自动填充,因为我希望有可能多次执行相同的查询并且
一次 Include()
导航 属性 但第二次忽略它。
ProjectTo<>()
方法具有允许我将导航属性包含到我的 select 中的参数,但我需要执行多级包含。这可能吗? Include(e => e.Collection.Select(sc => sc.MyProperty))
这样的语法在这种情况下不起作用。
我尝试对 DbContext
使用 Include().ThenInclude()
,然后执行 ProjectTo
,但在那种情况下 ProjectTo
覆盖了我的包含,它们被忽略了。
现在我不确定是否可以在映射中指定 ProjectTo
、ExplicitExpansion()
并具有多级包含?
你尝试了吗?
dbContext.Entities.ProjectTo<EntityDto>(dest => dest.Collection.Select(item => item.MyProperty));
I tried to use Include().ThenInclude() for DbContext and then perform ProjectTo, but in that case
ProjectTo
overrides my includes and they are ignored.
此覆盖按预期工作。
Select()
覆盖 Include()
EF documentation中明确提到了这一点:
If you change the query so that it no longer returns instances of the entity type that the query began with, then the include operators are ignored.
In the following example, the include operators are based on the
Blog
, but then theSelect
operator is used to change the query to return an anonymous type. In this case, the include operators have no effect.
包括
Include()
指示 EF 在获取请求的结果集时加载一些相关实体。此行为已添加到 EF 的默认加载行为中:
var people = db.People.ToList();
var peopleWithPets = db.People.Include(person => person.Pets).ToList();
通过添加 Include()
,您实质上扩展了枚举集合时发生在引擎盖下的加载行为(在本例中为 ToList()
)。
Select
Select()
用您定义的新行为覆盖默认加载行为。
var people = db.People.ToList();
var names = db.People.Select(person => person.Name).ToList();
当您调用 Select()
时,您实质上是指示 EF 不 执行其默认加载行为(这可能需要也可能不需要额外的包含),而是加载 完全您指定的内容(在本例中,person => person.Name
)。
ProjectTo<>()
是 Select()
的包装
您可以将 ProjectTo<TDestination>()
视为一种 SelectFactory
,它根据在 Automapper 中配置的 TDestination
映射生成适当的 Select
语句。
在幕后,EF 仍然执行 Select()
,因此在使用 ProjectTo<>()
.
如果您想包含其他相关实体或其任何属性,您需要扩展 Automapper 映射,而不是在查询中使用 Include
。如果您的映射包含其他字段,Automapper 将相应地扩展其底层 Select()
。
即使您能够使用 Include
包含相关实体,但如果您从未将它们定义为映射,Automapper 仍会忽略它们。