AutoMapper using EF Core persists and inheritance

555 Views Asked by At

I am using

  • .NET Core v3.1
  • EF Core v3
  • AutoMapper v9
  • AutoMapper.Collection.EntityFrameworkCore v1.0.1

and I am trying to add polymorph entities.

I have the following entities:

public abstract class Base
{
    public Guid Id { get; set; }
    public string Name { get; set; }
}

public class Child1 : Base
{
    public string Name2 { get; set; }
}

And corresponding dtos

public abstract class BaseDto
{
    public Guid Id { get; set; }
    public string Name { get; set; }
}

public class Child1Dto : BaseDto
{
    public string Name2 { get; set; }
}

I am registering them like that:

CreateMap<Base, BaseDto>()
   .IncludeAllDerived()
   .ReverseMap()
   .IncludeAllDerived();

CreateMap<Child1, Child1Dto>()
   .ReverseMap();

And also add do db context like that with discriminator:

modelBuilder.Entity<Base>()
   .HasDiscriminator<string>("type")
   .HasValue<Child1>("child1");

After that I try to add a new entry to the database like that:

var dto = new Child1Dto()
{
    Name = "Name",
    Name2 = "Name2",
};

var addedOrInserted = db.Set<Base>().Persist(_mapper).InsertOrUpdate(dto);

But for that case, I get the following exception:

Expression of type 'AutoMapper.EquivalencyExpression.EquivalentExpression2[Child1]' cannot be used for parameter of type 'AutoMapper.EquivalencyExpression.IEquivalentComparer2[Base]'

I think that this happens because the InsertOrUpdate is checking if the entity exists to check if an insert or an update should be performed.

Do you have any solution for that?

1

There are 1 best solutions below

0
On

It seems to be because you used CreateMap<Child1,Child1Dto>().ReverseMap(); when registering.

Even if they are inheritance relationship, it is not possible to directly add Child1Dto to Base, I think it may be necessary to use db.Set<Child1>.

Try to add public DbSet<Child1> Child1s { get; set; }in your context.

Then in your controller:

     Child1Dto basedto = new Child1Dto() 
            { 
                Id = new Guid(), 
                Name = "Name", 
                Name2 = "Name2" 
            };
     context.Child1s.Persist(mapper).InsertOrUpdate(basedto); 
     context.SaveChanges();

Result: enter image description here