Лучшее решение для десериализации универсального списка в Entity Framework Core 2.2 - PullRequest
0 голосов
/ 28 декабря 2018

Пожалуйста, сначала прочитайте код:

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?
            );

        });
    }
}

Объяснения:

  1. Example.DataList - это narchar(MAX) клоун в базе данных
  2. Data1, Data2, ..., DataN сохраняются в том же DataList
  3. Все модели, добавленные в DataList, могут быть успешно сериализованы в столбец "DataList"
  4. В 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 +

...