I am currently using automapper in my backend to map objects to models. I recently decided to use the following code to handle all my timezone conversions:
cfg.CreateMap<DateTime?, DateTime?>()
.ProjectUsing(i => DbFunctions.AddHours(i, offset.Hours));
cfg.CreateMap<DateTime, DateTime>()
.ProjectUsing(i => DbFunctions.AddHours(i, offset.Hours).Value);
Object.ProjectTo<ObjectModel>().SingleOrDefault();
then it works fine and the object is mapped and timezone converted
However when i am using the following code in my business layer to do a single object mapping:
Mapper.Map<Object, ObjectModel>(singleRecord);
It Gives an error : This function can only be invoked from LINQ to Entities.
stack trace :
at System.Data.Entity.DbFunctions.AddHours(Nullable`1 timeValue, Nullable`1 addValue)
at lambda_method(Closure , DateTime , DateTime , ResolutionContext )
at AutoMapper.ResolutionContext.Map[TSource,TDestination](TSource source, TDestination destination)
at lambda_method(Closure , Inventory , InventoryModel , ResolutionContext )
Mapper.Map is important to use in specific scenarios and i also don't want to project single records.
is there a way round this ?
By default AutoMapper will build a mapping
Func<TSource, TDestination>>
to be used byMap
method by compiling theExpression<TFunc<TSource, TDestionation>>
passed toProjectUsing
and used byProjectTo
, because usually it's enough and works. But not with EF canonical functions.You could override that behavior by specifying a different conversion to be used with
Map
method by providing explicitly bothProjectUsing
andConvertUsing
:From MSDN:
So the error is to be expected because the projection is not executed in a LINQ to Entities query.
The
DbFuncions.AddHours()
call is translated to a database function. Since in your business layer you're not passing an entity but an object, the error is thrown.You have two ways to work around the problem: 1. Use a different mapping logic in your bussiness layer. 2. Use a mapping logic that does not depend on the
DbFunctions
class so that it can be used in your DAL and business layer.