Автоматическое отображение с использованием ядра EF сохраняется и наследование

#c# #asp.net-core #automapper #ef-core-3.1

#c# #asp.net-core #автоматическое отображение #ef-core-3.1

Вопрос:

Я использую

  • .NET Core v3.1
  • EF Core v3
  • AutoMapper v9
  • Автоматическое отображение.Коллекция.EntityFrameworkCore v1.0.1

и я пытаюсь добавить полиморфные объекты.

У меня есть следующие объекты:

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

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

И соответствующие dto

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

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

Я регистрирую их так:

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

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

А также добавьте контекст do db, подобный этому, с помощью дискриминатора:

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

После этого я пытаюсь добавить новую запись в базу данных следующим образом:

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

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

Но в этом случае я получаю следующее исключение:

Выражение типа ‘AutoMapper.Выражение эквивалентности.Эквивалентное 2[Child1]' cannot be used for parameter of type 'AutoMapper.EquivalencyExpression.IEquivalentComparer выражение 2 [База]’

Я думаю, что это происходит потому InsertOrUpdate , что проверяется, существует ли объект, чтобы проверить, должна ли выполняться вставка или обновление.

Есть ли у вас какое-либо решение для этого?

Комментарии:

1. Какую базу данных вы используете? Может быть, лучше создать ваши таблицы в базе данных, а затем позволить инструментам VS создавать классы сущностей.

2. Привет @Flo, есть какие-либо обновления по этому делу?

3. @Yinqiu на самом деле я немного занят в последние дни. Но я вскоре протестировал ваше решение, и, похоже, оно работает. Но я хотел бы провести некоторые дополнительные тесты на нем. Это не оптимальное решение, потому что мне нужно создать один метод сохранения для каждого дочернего элемента.

4. Я думаю, это будет сложно. Если вы найдете лучшее решение, вы можете опубликовать его здесь и пометить как ответ, это будет полезно тем, у кого возникнет эта проблема в будущем.

Ответ №1:

Похоже, это потому, что вы использовали CreateMap<Child1,Child1Dto>().ReverseMap(); при регистрации.

Даже если они являются отношениями наследования, их невозможно напрямую добавить Child1Dto Base , я думаю, это может быть необходимо использовать db.Set<Child1> .

Попробуйте добавить public DbSet<Child1> Child1s { get; set; } в свой контекст.

Затем в вашем контроллере:

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

Результат:
введите описание изображения здесь