【问题标题】:AutoMapper ProjectTo ignoring .IncludeAutoMapper 项目忽略 .Include
【发布时间】:2017-12-29 02:12:11
【问题描述】:

我正在学习 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. 

这很简单,所以将这个操作分成两个独立的:首先获取 Parent,然后是 Mapper.Map。 此外,它可以在像这样更改地图时工作:

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

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

或者我什至应该以某种方式将计算转移到数据库端?但我想避免将此属性存储在数据库中。

【问题讨论】:

    标签: .net automapper entity-framework-core


    【解决方案1】:

    ProjectToQueryable.Select 的 Auto Mapper 等效项,因此生成的查询属于 EF Core Ignored Includes 类别。

    IQuerable&lt;T&gt; 查询一样,您应该使用可以映射到 SQL 的显式 表达式,例如像这样直接访问导航属性的东西

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

    请注意,虽然这应该填充所需的 WantedChildCount,但 Include 仍将被忽略。

    【讨论】:

    • 嗯,这很可悲。我想在 DB 层进行映射,我想我会重构我的 *Count 属性以某种方式在 DB 端计算。谢谢,我接受你的回答,因为它是正确的,而且我之前一直在阅读它。我问了一个问题,试图寻找替代方案......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-27
    • 1970-01-01
    • 2014-04-11
    • 2021-12-23
    • 1970-01-01
    • 2010-10-31
    • 1970-01-01
    相关资源
    最近更新 更多