0
votes

I have a set of classes.

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; }
}

I need to perform this mapping:

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)));

The following code causes an exception:

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

Exception info:

An unhandled exception of type 'System.NotSupportedException' occurred in EntityFramework.SqlServer.dll Additional information: Cannot compare elements of type 'System.Collections.Generic.ICollection`1[[EFTest.Entities.ScoreRecord, EFTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]'. Only primitive types, enumeration types and entity types are supported.

If I do not use the projection, then the mapping works correctly. The following code is executed without errors.

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

Why mapping with projection is failing and how to fix it?

Automapper version: 4.0.4,` EntityFramework version: 6.1

1

1 Answers

1
votes

It's because of a null check that happens when you have a map for a property. Check the execution plan.

You can avoid it by setting AllowNullDestinationValues to false (globally or per profile). Or you can upgrade and set AllowNull per member.