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