Reputation: 1551
Is there any way to map these EntityFramework
entities with AutoMapper?
I'm getting an error when trying to map a DateTime
object (from my DBContext entity) to a TimeSpan
property on my DTO.
This is the exception
----------- Exception #0 -----------
Type: System.NotSupportedException
Message: The specified type member 'TimeOfDay' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.
Source: EntityFramework
It used to work when mapping the Entity after ToList()
call, but now using AutoMapper's ProjectTo<>
IQueryable extension it is obviously trying to convert the expression to an expression that SQL can understand.
My question - is it possible to configure mapping on certain objects to take place after the query has been executed on the server? (e.g. after the ToList()
call)
CloseTime property on the DB entity is a DateTime
object but we are mapping to a TimeSpan
object
For Now - I'm just ignoring the properties like so
cfg.CreateMap<CustomerShipTo, ShipToBase>()
.ForMember(desc => desc.OpenTime, src => src.Ignore())
//.ForMember(desc => desc.OpenTime, src => src.CloseTime.TimeOfDay)
.ReverseMap();
Upvotes: 0
Views: 906
Reputation: 34673
.ProjectTo()
needs to be able to ultimately map down to SQL so there are limitations to what the mappings can do as compared to using .Map()
. A work-around for issues like this is to map a "raw" data value then use a translation property in the DTO. In your case since this is a data type conversion you could call the raw value "OpenDateTime", normally if I want to use the same name I will use a prefix of "Raw" to reflect the raw DB value. (I.e. RawOpenTime)
[Serializable]
public class ShipToBase
{
// ...
public DateTime OpenDateTime { get; set; }
public Timespan OpenTime
{
get { OpenDateTime.TimeOfDay; }
set { OpenDateTime = DateTime.MinValue().Add(value); } // Setter if needed.
}
}
Then in the mappings:
cfg.CreateMap<CustomerShipTo, ShipToBase>()
.ForMember(desc => desc.OpenDateTime, src => src.OpenTime)
.ForMember(desc => desc.OpenTime, src => src.Ignore())
.ReverseMap();
Upvotes: 4