自动映射器基于三元运算符映射接口

时间:2020-07-29 18:58:16

标签: c# entity-framework mapping linq-to-entities automapper

我正在使用AutoMapper 7.0.1版本。我有一个DTO班级:

public class Dto1{
    public IModel Model {get;set;}
}

public interface IModel {}

public class QuestionA: IModel {
    public string Text {get; set;}
}

public class QuestionB: IModel {
    public string Id {get;set;}
}

在创建Linq to Entity的过程中,遇到一个条件,并且基于该条件,我必须创建QuestionA类或ClassB的对象。我的映射就像:

CreatMap<SourceClass, Dto1>()  
      .ForMember(d=> d.Model, opt=> opt.MapFrom(src => src.Type == 0 ? 
                 new QuestionA()
                 {  
                     Text = src.Text
                 } : new QuestionB()
                 {
                     Id = src.Id
                 }));

我无法实现此行为。我收到运行时异常为:

无法将类型“ QuestionA”强制转换为类型“ IQuestionTypeModel”。 LINQ to Entities仅支持转换EDM原语或枚举类型。

1 个答案:

答案 0 :(得分:0)

三元运算符的两端必须返回相同的类型。尽管事实上QuestionAQuestionB都实现了IModel,但是您需要将它们明确标记为相同的类型:

CreateMap<SourceClass, Dto1>()
    .ForMember(
        d => d.Model,
        opt => opt.MapFrom(src =>
            src.Type == 0
            ? new QuestionA() { Text = src.Text } as IModel
            : new QuestionB() { Id = src.Id } as IModel));

编辑#1

我在本地使用SQL Server进行尝试,该服务器具有上述配置和AutoMapper Querable Extensions ProjectTo()

var result = dbContext
    .Set<SourceClass>()
    .ProjectTo<Dto1>(configuration)
    .ToList();

我已经收到有效的结果。 EF Core生成了这样的查询:

SELECT CASE
    WHEN [s].[Type] = 0 THEN CAST(1 AS bit)
    ELSE CAST(0 AS bit)
END, [s].[Text], [s].[Id]
FROM [SourceClass] AS [s]