AutoMapper IQueryable Extension' s 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;}
}
引发此异常:
无法比较“App.Domain.MyComplexType”类型的元素。只有原始类型, 支持枚举类型和实体类型。
我有这个型号:
IQueryable<MyEntityType>
我使用AutoMapper配置从ViewModel
到Mapper.CreateMap<MyEntityType, MyComplexType>(); // I rely on AutoMapper's
//convention for flattening `source.MyComplexType.Property1` to `dest.MyComplexTypeProperty1'
的映射:
var myItem = myContext.Where(x => x.Id == id).Project().To<ViewModel>().SingleOrDefault();
然后我尝试检索这样的单个项目:
SingleOrDefault()
调用SingleOrDefault()
时出现上述异常,显然是
我目前通过首先调用var myItem = Mapper.Map<ViewModel>(myContext.Find(id));
然后进行映射来解决这个问题,这有效:
Where
其他帖子基本上说当尝试将EF复杂类型与null进行比较时会产生上述错误,例如,在{{1}}子句中,但这显然不是这种情况。
答案 0 :(得分:4)
LINQ to实体无法按照您的建议对复杂类型执行比较(空检查)。例如,这不起作用......
myContext.Select(i => new
{
MyComplexType = i.MyComplexType != null ?
new MyComplexTypeViewModel()
{
Property1 = i.MyComplexType.Property1
}
: null
})
默认情况下,Automapper会尝试将空源值映射为空值,有时在使用Project().To<>()
或Mapper.Engine.CreateMapExpression<,>()
时会在生成的表达式中添加类似的条件。
在我的情况下,我将整个复杂类型映射到它自己的viewmodel并且没有使用属性展平。这个配置值为我解决了这个问题...
Mapper.AllowNullDestinationValues = false;
您可以尝试使用CreateMapExpression<TSource,TDest>()
手动创建映射表达式,并查找复杂类型的空检查以查看它是否是相同的情况。
答案 1 :(得分:2)
让你的道具可以为空
public decimal? MyComplexTypeProperty1 { get;set; }
然后使用这个映射
Mapper.CreateMap<MyEntityType, MyComplexType>()
.ForMember(p => p.MyComplexTypeProperty1, p => p.AllowNull())
如果你想解决所有复杂类型的问题,那么你可以在创建 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
});