自动映射器:通过投影将集合映射到单个对象

时间:2019-04-04 08:07:43

标签: entity-framework automapper

我有一组课程。

public class Student
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    public string Name { get; set; }
    public virtual ICollection<ScoreRecord> ScoreRecords { get; set; }
}

public class ScoreRecord
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    public int StudentId { get; set; }
    public virtual Student Student { get; set; }
    public string Subject { get; set; }
    public int Score { get; set; }
}

public class ScoreModel
{
    public int MinScore { get; set; }
    public int MaxScore { get; set; }
}

public class StudentViewModel
{
    public int Id { get; set; }

    public string Name { get; set; }

    public ScoreModel Score { get; set; }
}

我需要执行此映射:

Mapper.CreateMap<Student, StudentViewModel>()
    .ForMember(d => d.Score, opts => opts.MapFrom(m => m.ScoreRecords));
Mapper.CreateMap<ICollection<ScoreRecord>, ScoreModel>()
    .ForMember(d => d.MinScore, opts => opts.MapFrom(m => m.Min(s => s.Score)))
    .ForMember(d => d.MaxScore, opts => opts.MapFrom(m => m.Max(s => s.Score)));

以下代码导致异常:

var student = context.Students.ProjectTo<StudentViewModel>().FirstOrDefault(e => e.Id == 1);

异常信息:

  

发生类型为'System.NotSupportedException'的未处理异常   在EntityFramework.SqlServer.dll中        其他信息:无法比较类型'System.Collections.Generic.ICollection`1 [[EFTest.Entities.ScoreRecord,   EFTest,版本= 1.0.0.0,文化=中性,PublicKeyToken =空]]”。只要   支持基本类型,枚举类型和实体类型。

如果我不使用投影,则映射可以正常工作。以下代码执行无误。

var student = ctx.Students.FirstOrDefault(e => e.Id == 1);
var studentViewModel = Mapper.Map<StudentViewModel>(student);

为什么投影投影失败以及如何解决?

Automapper version: 4.0.4,`EntityFramework版本:6.1

1 个答案:

答案 0 :(得分:1)

这是因为拥有属性映射时发生空检查。选中the execution plan

您可以通过将AllowNullDestinationValues设置为false(全局或针对每个配置文件)来避免这种情况。或者,您可以升级并为每个成员设置AllowNull。