AutoMapper IQueryable Extension's Project().To<TViewModel>().SingleOrDefault()
throws this exception:
Cannot compare elements of type 'App.Domain.MyComplexType. Only primitive types, enumeration types and entity types are supported.
I have this model:
public class MyEntityType // this is an entity type on the dbContext
{
public int Id {get;set;
public MyComplexType MyComplexType {get;set;}
}
public class MyComplexType // this is a complex type
{
public decimal Property1 { get; set;}
public string Property2 { get;set;}
}
public class ViewModel
{
public int Id { get;set;}
public decimal MyComplexTypeProperty1 { get;set;}
}
I use AutoMapper to configure mapping from IQueryable<MyEntityType>
to ViewModel
:
Mapper.CreateMap<MyEntityType, MyComplexType>(); // I rely on AutoMapper's
//convention for flattening `source.MyComplexType.Property1` to `dest.MyComplexTypeProperty1'
Then I try to retrieve a single item like this:
var myItem = myContext.Where(x => x.Id == id).Project().To<ViewModel>().SingleOrDefault();
I get the above exception when SingleOrDefault()
is called, so apparently
I currently work around this by first calling SingleOrDefault()
and then doing the mapping, this works:
var myItem = Mapper.Map<ViewModel>(myContext.Find(id));
Other posts basically say that the error above arises when trying to compare a EF Complex Type with null, as, e.g., in a Where
clause, but that is apparently not the case here.
LINQ to entities is unable to perform compare (null check) for complex types as you suggested. For example this does not work...
myContext.Select(i => new
{
MyComplexType = i.MyComplexType != null ?
new MyComplexTypeViewModel()
{
Property1 = i.MyComplexType.Property1
}
: null
})
By default Automapper tries to map null source values as nulls and sometimes adds similar conditions in generated expression when using Project().To<>()
or Mapper.Engine.CreateMapExpression<,>()
.
In my case i was mapping whole complex type to it's own viewmodel and did not use property flattening. This configuration value solved the issue for me...
Mapper.AllowNullDestinationValues = false;
You may try to manually create mapping expression using CreateMapExpression<TSource,TDest>()
and look for null checks on complex type to see if it's the same situation.
make your prop Nullable
public decimal? MyComplexTypeProperty1 { get;set; }
then use this mapping
Mapper.CreateMap<MyEntityType, MyComplexType>()
.ForMember(p => p.MyComplexTypeProperty1, p => p.AllowNull())
and if you want solve problems for all complex types, then you can use this code in creating MapperConfiguration
var config = new MapperConfiguration(cfg =>
{
cfg.ForAllPropertyMaps(p =>
p.SourceType == typeof(MyComplexType) ||
p.SourceType == typeof(AnotherComplexType) // || ...
//NOTE: if you have another ComplexTypes so remove prev lines
// and use this line to handle all of them
//p.SourceType.GetCustomAttributes(typeof(ComplexType))
(p, q) => { q.AllowNull(); }
);
//other configs
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With