c# Как настроить и добавить один класс, содержащий список производных классов, в базу данных, используя Entity Framework Core 3.1.x - PullRequest
0 голосов
/ 27 марта 2020

Я хотел бы добавить модель, которая может иметь много производных объектов, в отдельные таблицы и игнорировать BaseObject в базе данных. Производные объекты находятся в общем списке c BaseObject.

Как лучше всего добавить модель, производную от которой BaseObject, к базе данных SQL Server? Как определить ключи и внешние ключи (используя Fluent API) для ie. каждый производный объект имеет внешний ключ для Model -> ModelFK. Я хочу, чтобы база данных генерировала эти ключи. Обратите внимание, что BaseObjectDictionary используется для других целей.

Я пробовал это разными способами, но сейчас я полностью застрял в этом. Я хотел бы знать, каким образом я должен сделать отношения (Модель имеет BaseObjects (или производные классы)) или наоборот?

Вопрос в том, как добавить BaseObjects в отдельные таблицы (по одной на Derived type), когда они расположены в Model как List<BaseObject>?

Я знаю, что для ie существует множество ограничений. Класс Table-Per-Concrete все еще находится в разработке и не работает в текущем EF Core 3.x ->, запланированном на 5.x или более позднюю версию.

public sealed class OCContext : DbContext
{
        public OCContext(DbContextOptions options): base(options) { }      
        public OCContext() {}        
        public DbSet<ModelDto> Models { get; set; }

        public DbSet<BaseObject> BaseObjects { get; set; }

        public DbSet<IntegerObject> IntegerObjects { get; set; }
        public DbSet<IntegerListObject> IntegerListObjects { get; set; }
        public DbSet<StringObject> StringObjects { get; set; }
        public DbSet<DoubleObject> DoubleObjects { get; set; }
        public DbSet<CurveObject> CurveObjects { get; set; }
        public DbSet<BooleanObject> BooleanObjects { get; set; }      

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Ignore<BaseObject>();  

            modelBuilder.Entity<IntegerObject>().ToTable("IntegerObject");
            modelBuilder.Entity<IntegerListObject>().ToTable("IntegerListObject");
            modelBuilder.Entity<StringObject>().ToTable("StringObject");               
            modelBuilder.Entity<DoubleObject>().ToTable("DoubleObject");
            modelBuilder.Entity<CurveObject>().ToTable("CurveObject");
            modelBuilder.Entity<BooleanObject>().ToTable("BooleanObject");
        }
}    

public class Model 
{
    public Model() {}

    public IDictionary<string, BaseObjects> BaseObjecsDictionary { get; set; }

    public IList<BaseObject> BaseObjects => BaseObjects.Values.ToList();

    public ModelDto(string name, IList<BaseObject> baseObjects)
    {
        this.Name = name;
        this.BaseObjecsDictionary = baseObjects.ToDictionary(x => x.Name, x => x);      
    }
}

abstract BaseObject
{
    public int ModelId
    public Name
    public Type @Type => BoxedValue.GetType();
}

public class StringObject : BaseObject 
{
    public string Value { get; }
    public override object BoxedValue => Value;
    public StringObject(){ }

    public StringObject(string name, EnumUnit unit, string value)
    {
        this.Name = name;
        this.Unit = unit;
        this.Value = value;
    }
}

public class CustomObject : BaseObject 
{
    public CustomObj Value { get; }
    public override object BoxedValue => Value;
    public CustomObject(){ }

    public CustomObject(string name, EnumUnit unit, CustomObj value)
    {
        this.Name = name;
        this.Unit = unit;
        this.Value = value;
    }
}

public class BooleanObject : BaseObject 
{
    public string Value { get; }

    public override object BoxedValue => Value;

    public BooleanObject() 
    { }

    public BooleanObject(string name, EnumUnit unit, string value)
    {
        this.Name = name;
        this.Unit = unit;
        this.Value = value;
    }
}

public class IntegerObject : BaseObject 
{
    public int Value { get; }

    public override object BoxedValue => Value;

    public IntegerObject()
    { }

    public IntegerObject(string name, EnumUnit unit, int value)
    {
        this.Name = name;
        this.Unit = unit;
        this.Value = value;
    }
}

public class IntegerListObject : BaseObject 
{
    public IList<int> Value { get; }

    public override object BoxedValue => Value;

    public IntegerListObject()
    { }

    public IntegerListObject(string name, EnumUnit unit, IList<int> value)
    {
            this.Name = name;
            this.Unit = unit;
            this.Value = value;
    }
}

public class DoubleObject : BaseObject 
{
    public double Value { get; }

    public override object BoxedValue => Value;

    public DoubleObject()
    { }

    public DoubleObject(string name, EnumUnit unit, double value)
    {
        this.Name = name;
        this.Unit = unit;
        this.Value = value;
    }
}

..

modelBuilder.Entity<BaseObject>()
       .HasOne(e => e.Model)
       .WithMany(c => c.BaseObjects)
       .HasForeignKey("ModelId");

Это дает мне ошибку:

Тип сущности 'IntegerObject' не может быть сопоставлен с таблицей, потому что он является производным от 'BaseObject'. Только базовые типы объектов могут быть сопоставлены с таблицей.

Кто-нибудь знает обходной путь для этого, чтобы я мог сохранять производные классы в отдельных таблицах?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...