AutoMapper Project忽略.Include

时间:2017-07-23 11:26:39

标签: .net automapper entity-framework-core

我在学习Automapper和EF Core时偶然发现了一个问题,同时尝试建模基于导航属性计算的get-only属性。 我有两个模特:

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;}
}

一个DTO:

public class VM
{
    public string Name{get;set;}
    public int WantedCount{get;set;}
}

尝试从Parent中自动执行VM,如:

var c = context.Parents.Include(p => p.Childs).ProjectTo<VM>().FirstOrDefault();

Automapper配置如下:

Mapper.Initialize(cfg=>
    cfg.CreateMap<Parent, VM>()
    .ForMember(d=>d.WantedCount, o => o.MapFrom(s=>s.WantedChildCount));

问题在于,在生成的VM字段中,没有填充WantedCount。在日志中我找到了消息

The Include operation for navigation: 'p.Childs' was ignored because the target navigation is not reachable in the final query results. 

这很简单,所以将此操作拆分为两个单独的:首先取父素,然后取Mapper.Map。 此外,它可以在更改地图时起作用:

cfg.CreateMap<Parent, VM>()
    .ForMember(d=>d.WantedCount, o => o.MapFrom(s=>s.Childs(c=>c.Type!=1));

但是这样我完全忽略了模型中的get-only属性。 我想了解问题所在,我该如何解决。

或者我甚至可能以某种方式将计算移到DB端?但我想避免将此属性存储在数据库中。

1 个答案:

答案 0 :(得分:2)

ProjectTo是自动映射器等效于Queryable.Select,因此生成的查询属于EF Core Ignored Includes类别。

IQuerable<T>查询一样,您应该使用可以映射到SQL的显式表达式,例如:像这样的东西直接导航属性

o.MapFrom(s => s.Childs.Count(c => c.Type != 1))

请注意,虽然这应填充所需的WantedChildCount,但仍会忽略Include