I'm trying to auto project from SQL server with Automapper some data into my view models.
The view model I have is:
public sealed class WorkstationViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public string OccupiedByName { get; set; }
}
And the code I'm trying to use is:
Mapper.CreateMap<Workstation, WorkstationViewModel>()
.ForMember(T => T.OccupiedByName, T => T.MapFrom(W =>
W.Sessions.AsQueryable().Select(E => E.StaffMember.Name).SingleOrDefault()));
Two properties Id
and Name
are auto-projected as they have equal names in Workstation
class.
The exception I get on some codelines like this
var model = WorkstationsRepository.GetAll().Project()
.To<WorkstationViewModel>().SingleOrDefault();
is some weird object reference is null
exception and on the top of the stack trace there are some automapper's CreateExpression<>
methods which gives me a conclusion that the automapper cannot generate a good one expression to translate it to SQL code.
When I use simple maps, like .Name
to .Category.Name
or other one-item retrievals from the SQL table, it works perfectly. All I need is to get access to multiple items while projecting the sequence via Automapper.
The newer Project().To()
API takes a totally different route than the "classic" Mapper.Map()
API. I think that the latter would run in your case, but of course you won't have the benefit of the projection trickling thought to the SQL.
During Project().To()
AutoMapper tries to get MemberInfo
s (reflection) from the involved types, which it uses to create lambda expressions. This means that the source properties in a mapping must be members of the source type. Evidently, W.Sessions.AsQueryable().Select(...
is not a member of Workstation
. So somewhere along the line AutoMapper bumps into a null
memberinfo.
So, Project().To()
is a bit restricted. In this particular case a remedy may be to map a Session
with its parents WorkStation
and StaffMember
to the model. Reference navigation properties will map OK with Project().To()
.