sor*_*lex 4 .net automapper entity-framework-core
我正在学习 Automapper 和 EF Core,并在尝试对基于导航属性计算的仅获取属性进行建模时偶然发现了一个问题。我有两个模型:
public class Parent
{
public int Id {get;set;}
public string Name {get;set;}
public ICollection<Child> Childs {get;set;}
public int WantedChildCount {get{return Childs?.Count(c=>c.Type!=1)??0;}
}
public class Child
{
public int Id {get;set;}
public string Name {get;set;}
public int Type {get;set;}
}
Run Code Online (Sandbox Code Playgroud)
一个 DTO:
public class VM
{
public string Name{get;set;}
public int WantedCount{get;set;}
}
Run Code Online (Sandbox Code Playgroud)
并尝试从父级自动映射虚拟机,例如:
var c = context.Parents.Include(p => p.Childs).ProjectTo<VM>().FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)
自动映射器配置如下:
Mapper.Initialize(cfg=>
cfg.CreateMap<Parent, VM>()
.ForMember(d=>d.WantedCount, o => o.MapFrom(s=>s.WantedChildCount));
Run Code Online (Sandbox Code Playgroud)
问题是生成的 VM 字段 WantedCount 未填充。在日志中我发现了消息
The Include operation for navigation: 'p.Childs' was ignored because the target navigation is not reachable in the final query results.
Run Code Online (Sandbox Code Playgroud)
这很容易,因此将此操作分成两个单独的操作:首先获取 Parent,然后获取 Mapper.Map。此外,它可以在像这样更改 Map 时工作:
cfg.CreateMap<Parent, VM>()
.ForMember(d=>d.WantedCount, o => o.MapFrom(s=>s.Childs(c=>c.Type!=1));
Run Code Online (Sandbox Code Playgroud)
但这样我将完全忽略模型中的仅获取属性。我想了解问题是什么,以及如何解决它。
或者也许我什至应该以某种方式将计算转移到数据库端?但我想避免将此属性存储在数据库中。
ProjectTo是 Auto Mapper 等效项Queryable.Select,因此生成的查询属于 EF Core Ignored Includes类别。
与通常的IQuerable<T>查询一样,您应该使用可以映射到 SQL 的显式表达式,例如直接访问导航属性
o.MapFrom(s => s.Childs.Count(c => c.Type != 1))
Run Code Online (Sandbox Code Playgroud)
请注意,虽然这应该填充所需的WantedChildCount,但Include仍会被忽略。