AutoMapper IQueryable Extension抛出&#34;无法比较<complex type =“”>&#34;类型的元素同

时间:2015-05-12 17:01:57

标签: c# entity-framework automapper

AutoMapper IQueryable Extension&#39; 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配置从ViewModelMapper.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}}子句中,但这显然不是这种情况。

2 个答案:

答案 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
});