Reputation: 3036
Question about the AutoMapper. I am trying to project IQueryable to DTO using construction expression but result always have null's in its fields.
public class BaseObject { }
public class DTO { public string Name { get; set; } }
....
// create map BaseObject-to-DTO
Mapper.CreateMap<BaseObject, DTO>()
.ConstructProjectionUsing(s => new DTO
{
Name = "This name will never appear in DTO"
});
// create object array with one element
var objects = new [] { new BaseObject() };
var result = objects.AsQueryable().ProjectTo<DTO>(); // here Name = null everywhere
Why the Name in results is null?
Upvotes: 1
Views: 923
Reputation: 26765
This is the expected behavior. AutoMapper is trying to build a "Select" projection. A normal source/destination projection without AutoMapper would look something like this in LINQ:
objects.AsQueryable().Select(bo => new DTO { Name = bo.Name });
I go through the source/destination members and build up what's known as a MemberInitExpression
in LINQ. That's the construction expression plus member initialization, new + curly brace property assignments.
ConstructProjectionUsing
is about replacing just the "new" part of the member init expression: bo => new DTO("I like turtles") { Name = bo.Name };
and not the individual members. For what you're looking for, I'd actually have to merge two member initialization expressions - one that AutoMapper builds from the source/destination properties, and whatever you've put in the configuration. My head hurts thinking about how to do that effectively.
I could probably throw a configuration exception if you tried to do otherwise, or at least had better IntelliSense comments. Feel free to open a GH issue for that!
Upvotes: 1
Reputation: 25019
ConstructProjectionUsing
accepts constructor only, I guess. It works fine with:
.ConstructProjectionUsing(s => new DTO("This name will never appear in DTO"))
Answer to question "why" lies deep in Automapper sources.
Upvotes: 0