#c# #entity-framework #entity-framework-core
Вопрос:
Поэтому, сохраняя сложные объекты в базе данных, я преобразую объект в строку JSON путем сериализации объекта. Для считывания его обратно как объекта применяется десериализация JSON. Пока все работает нормально.
modelBuilder.Entity<Order>()
.Property(e => e.MyAddress)
.HasConversion(
x => FromAddress(x),
x => ToAddress(x)
);
protected Address ToAddress(string address)
{
return JsonSerializer.Deserialize<Address>(address, null);
}
protected string FromAddress(Address address)
{
return JsonSerializer.Serialize(address, null);
}
Мой вопрос в том, могу ли я каким-либо образом передать другой аргумент в свой конвертер из Entity Framework для десериализации? Мне это нужно, потому Address
что модель на самом деле будет 3-х типов. Все наследуются от BaseAddress
класса. Во время десериализации мне нужно зависеть от другого поля из той же таблицы, которое поможет ему определить, в какую дочернюю модель его необходимо десериализовать.
protected Address ToAddress(string address, int type)
{
if(type == 1)
return JsonSerializer.Deserialize<AddressOne>(address, null);
else if (type == 2)
return JsonSerializer.Deserialize<AddressTwo>(address, null);
else if (type == 3)
return JsonSerializer.Deserialize<AddressThree>(address, null);
else
return JsonSerializer.Deserialize<Address>(address, null);
}
Ответ №1:
Это невозможно по замыслу, поскольку EF не позволяет передавать какие-либо дополнительные параметры делегатам HasConversion.
Это действительно требует перепроектирования для нормализации и разделения адресных данных в отдельную таблицу или таблицы. Вы можете использовать одну таблицу и использовать таблицу для иерархии (TPH) или несколько таблиц-по 1 для каждого типа адреса-и использовать таблицу для каждого типа (TPT). TPH доступен как в EF6, так и в EFCore, но на данный момент TPT доступен только в EF6.
Вот пример практической реализации TPH.
Пожалуйста, ознакомьтесь с документами Microsoft по наследованию EF.