EF Core - Как создавать унаследованные типы сущностей, которые содержат столбцы внешнего ключа - PullRequest
0 голосов
/ 02 сентября 2018

Я использую подход таблицы к иерархии для достижения наследования в типах сущностей. У меня определены 3 класса:

Номер - Базовый класс

SubMapRoom - Наследуется от Room

OverviewRoom - Наследуется от Room

В БД у меня есть только одна таблица с именем Room, в которой есть столбцы SubMapRoom и OverviewRoom. Он также содержит столбец «Дискриминатор» для указания типа.

Сначала я попытался переместить все столбцы SubMapRoom в классе Room в класс SubMapRoom. 1 из столбцов содержит внешний ключ для другой таблицы с именем Status. После этого я попытался указать отношение внешнего ключа для типа сущности SubMapRoom в OnModelCreating (). Тем не менее, я получаю ошибку компиляции при попытке сделать это. В методе EF Core OnModelCreating () у меня есть этот код (помечена строка, которая содержит ошибку ниже):

modelBuilder.Entity<SubMapRoom>(entity =>
{
    entity.HasOne(d => d.UnassignedDoctorStatus)
        .WithMany(p => p.Room) **ERROR HAPPENS HERE**
        .HasForeignKey(d => d.UnassignedDoctorStatusId)
        .OnDelete(DeleteBehavior.Cascade)
        .HasConstraintName("FK_Room_UnassignedStatusID");
});

modelBuilder.Entity<Room>()
    .HasDiscriminator<int>("RoomType")
    .HasValue<SubMapRoom>(1)
    .HasValue<OverviewRoom>(2);

Я получаю эту ошибку:

Невозможно преобразовать лямбда-выражение в предполагаемый тип делегата, поскольку некоторые из возвращаемых типов в блоке неявно не преобразуются в возвращаемый тип делегата

Я знаю, что могу решить эту проблему, изменив другой класс (Status) на использование унаследованного типа вместо базового типа для свойства навигации, но это неправильный путь. Я чувствую, что здесь чего-то не хватает. Как правильно определить отношение внешнего ключа в унаследованном типе сущности?

[EDIT] Вот классы для 4 моделей, на которые я ссылался здесь:

public abstract class Room
{
    public Room()
    {
        InverseLinkedRoom = new HashSet<Room>();
    }

    public int Id { get; set; }
    public int SubMapId { get; set; }
    public string MapLabel { get; set; }
    public string RoomLabel { get; set; }
    public int LeftCoordinate { get; set; }
    public int TopCoordinate { get; set; }
    public int Width { get; set; }
    public int Height { get; set; }
    public int? LinkedRoomId { get; set; }
    public int RoomType { get; set; }

    public Room LinkedRoom { get; set; }
    public SubMap SubMap { get; set; }
    public PatientQueue PatientQueue { get; set; }
    public ICollection<Room> InverseLinkedRoom { get; set; }
}

public class SubMapRoom : Room
{
    public int? UnassignedDoctorStatusId { get; set; }

    public Status UnassignedDoctorStatus { get; set; }
}

// Note: Have not yet attempted to move base class members in here
public class OverviewRoom : Room
{
}

public partial class Status
{
    public Status()
    {
        Room = new HashSet<Room>();
    }

    public int Id { get; set; }
    public string EnumId { get; set; }
    public bool Active { get; set; }
    public bool IsFastBlink { get; set; }

    public ICollection<Room> Room { get; set; }
}

1 Ответ

0 голосов
/ 02 сентября 2018

Спасибо за помощь всем. Я пересмотрел свою схему БД и решил внести некоторые изменения, которые устранят эту проблему. На самом деле оказывается, что мою новую схему проще использовать в коде, чем я думал. На самом деле, это намного проще. Я думаю, что пытался переоценить это. Поэтому иногда решение состоит в том, чтобы просмотреть вашу схему и выяснить, имеет ли она смысл в первую очередь. По сути, я переместил унаследованные классы в отдельную таблицу с отдельным идентификатором. Потому что, в конце концов, они являются логически отдельными типами сущностей и связаны только с точки зрения данных. В коде они служат разным целям, даже если они имеют одни и те же столбцы.

В конце концов, единственным недостатком этого подхода является то, что я нарушаю DRY для другой таблицы (в ней 5 повторяющихся столбцов). В противном случае многие другие операции легче кодировать, чем раньше. Я готов жить с этим, а не заниматься всем этим сейчас. Позже я могу попытаться использовать таблицу в иерархии, если мне нужно добавить тонны новых столбцов в обе таблицы.

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