Entity Framework Code First - Наследование - Коллекции связанных элементов

Я пытаюсь реализовать модель в EF6, используя наследование

У меня есть следующие классы:
База
Комментарии
Страница: База
BlogPost: База

Где и Page, и BlogPost используют комментарии одинаково. Поэтому я определяю базу как

public class Base
{
    public int ID { get; set; }
    // ...
    public ICollection<Comment> Comments { get; set; }
}

И класс комментариев определяется так:

public class Comment
{
    public int ID { get; set; }
    public int RelatedItemID { get; set; } // points to Base::ID
    public string Text { get; set; }
}

Предположим, я хочу настроить базу данных как "Таблица для каждого типа", поэтому для Page и BlogPost существуют отдельные таблицы, каждая с автоматическим приращением int PK.

Теперь EF знает, на какую таблицу указывает Comment.RelatedItemID? то есть Page или BlogPost

Каков наилучший способ реализовать это, не прибегая к "Таблице в иерархии"?

1 ответ

Решение

Я хочу настроить базу данных как "Таблица для каждого типа", поэтому для Page и BlogPost существуют отдельные таблицы, каждая с автоматическим приращением int PK

Здесь проблема.
Описание выглядит как TPC, но поскольку вы хотите использовать первичные ключи с автоинкрементом для каждого потомка, оно не будет соответствовать TPC, поскольку в конечном итоге вы получите дублирующие первичные ключи в одном наборе сущностей. Очевидно, что это тоже не TPT, потому что TPT предполагает, что существует "базовая" таблица с идентификаторами автоинкремента, в то время как "производные" таблицы имеют первичные ключи без автоинкремента, которые в то же время являются внешними ключами для "базовый" стол.

Мне кажется, что логически эти сущности не связаны. Я имею в виду, что не бывает случаев, когда вы захотите запросить страницы и записи в блоге, используя один запрос. Следовательно, лучше избегать наследования в модели EF.

Я предлагаю вам изменить дизайн модели следующим образом:

// "abstract" tells EF, that this type doesn't require mapping
public abstract class CommentBase
{
    public int ID { get; set; }
    public int RelatedItemID { get; set; }
    public string Text { get; set; }
}

public class PageComment: CommentBase {}
public class BlogPostComment :  CommentBase {}

public abstract Base<TComment>
    where TComment : Comment
{
    public int ID { get; set; }
    // ...
    public ICollection<TComment> Comments { get; set; }
}

public class Page : Base<PageComment> { /* other page properties */ }
public class BlogPost : Base<BlogPostComment> { /* other blog post properties */ }

В коде все еще есть наследование, но в модели EF будет два разных набора сущностей. OTOH, вы получите две отдельные таблицы с комментариями - одну для страниц, одну для сообщений в блоге.

Другие вопросы по тегам