Пожалуйста, сначала прочитайте код:
public class Example
{
public int Id { get; set; }
public string Name { get; set; }
public List<RootData> DataList { get; set; } //Generic list for all kind of RootData
}
public class RootData
{
public string RootProperty { get; set; }
}
public class Data1 : RootData
{
public string DataProperty1 { get; set; }
}
public class Data2 : RootData
{
public string DataProperty2 { get; set; }
}
...
public class DataN : RootData
{
public string DataPropertyN { get; set; }
}
public partial class ExampleContext : DbContext
{
public ExampleContext(DbContextOptions<ExampleContext> options)
: base(options)
{
}
public virtual DbSet<Example> Examples { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Ignore<RootData>();
modelBuilder.Entity<Example>(entity =>
{
entity.Property(p => p.DataList).HasConversion(
x => JsonConvert.SerializeObject(x)
, x => JsonConvert.DeserializeObject<List<RootData>>(x) //<== it forces all data back to root type, but not its right type. how can I customize this code?
);
});
}
}
Объяснения:
- Example.DataList - это
narchar(MAX)
клоун в базе данных Data1
, Data2
, ..., DataN
сохраняются в том же DataList
- Все модели, добавленные в
DataList
, могут быть успешно сериализованы в столбец "DataList" - В
DataList
, никто не знает, сколько классов получено из RootData
, и они находятся в разных пространствах имен.
Здесь проблема в следующем:
JsonConvert.DeserializeObject<List<RootData>>(x)
Не можетбыть десериализованными объектами обратно в исходное data model
.как я могу это изменить?
Решение, о котором я могу подумать:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
....
modelBuilder.Entity<Example>(entity =>
{
entity.Property(p => p.DataList).HasConversion(
x => JsonConvert.SerializeObject(x)
, x => JsonConvert.DeserializeObject<List<object>>(x).Select(DeserializeDataObject).ToList()
);
});
}
protected virtual RootData DeserializeDataObject(object obj)
{
//cast objects again with a switch-case block
return new Data1();//<= for example only
}
Но сначала я должен знать все производные классы.как я могу настроить этот код?
Среда:
ASP.NET core 2.2+, Visual Studio 2017, Microsoft SQL Server 2016 +