AutoMapper ProjectTo ignoring .Include

.net automapper entity-framework-core

Question

I'm learning Automapper, and EF Core, and stumbled onto a problem, while trying to model get-only property, which is calculated based on navigation property. I'm having two models:

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

One DTO:

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

And trying to automap VM from Parent like:

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

Automapper configured like this:

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

The problem is that in resulting VM field WantedCount isn't populated. In logs I've found message

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

It's easy so split this operation into two separate: first take Parent, and then Mapper.Map. Also, it could work when changing Map like this:

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

But this way I'll ignore get-only property in model totally. I'd like to understand what the problem is, and how could I solve it.

Or maybe I should even somehow move calculation to DB side? But I'd like to avoid storing this property in database.

1
1
7/23/2017 11:26:38 AM

Accepted Answer

ProjectTo is the Auto Mapper equivalent of Queryable.Select, hence the resulting query fall into EF Core Ignored Includes category.

As usual with IQuerable<T> queries, you should use explicit expression which can be mapped to SQL, e.g. something like this accessiong directly the navigation property

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

Note that while this should populate the desired WantedChildCount, the Include will still be ignored.

3
7/23/2017 3:31:25 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow