Entity Framework 7 и условные внешние ключи

Устаревшая база данных, с которой я работаю, использовала такой шаблон, как

CREATE TABLE [Document](
    [ID] [bigint] IDENTITY(1,1) NOT NULL,
    [EntityTypeID] [int] NOT NULL,  -- Tells us if the document is for a item, person, company....
    [EntityID] [bigint] NOT NULL,   -- Is the primary key value from the item, person, company table
    [Url] [nvarchar](1024) NULL,
)

В таблице документов не определен FK, поскольку каждая запись может описывать данные, относящиеся к другой родительской таблице.

Пример:

Таблица документов

ИДЕНТИФИКАТОР EntityTypeID EntityID URL 1 1 123 ... 2 1 123 ... 3 2 123 ... 4 2 123 ... 5 3 567 ... 6 3 456 ...

Таблица лиц

ИДЕНТИФИКАТОР Имя 123 Дэйв

Таблица элементов

ИДЕНТИФИКАТОР Имя 123 Наушники

Стол компании

ИДЕНТИФИКАТОР Имя 567 Акме 456 Глолекс

Скажем, идентификаторы EntityTypeID определены как Person = 1, Item = 2 и Company = 3. Тогда

Document.ID 1 and 2 are Dave's documents
Document.ID 3 and 4 are documents about Headphones  
Document.ID 5 are documents for Acme
Document.ID 6 are documents for Globlex

Моей первой мыслью было создать представления для PersonDocument, ItemDocument и CompanyDocument. и в OnModelCreating сделайте что-то вроде

modelBuilder.Entity<PersonDocument>(entity => 
{
  ...
  entity.HasOne(d => d.Person).WithMany(p => p.PersonDocument).HasForeignKey(d => d.EntityId);
  ...
 }

Это работает для чтения данных и заполнения моих классов DTO, но я не знаю, смогу ли я обновить или создать новые записи документов, используя этот подход.

Когда я пытаюсь добавить документ, я получаю

The entity type 'PersonDocument' is not mapped to a table, therefore the entities cannot be persisted to the database. Call ToTable

Как мне справиться с этим?

В прошлом я много боролся с этими полиморфными ассоциациями. Мой окончательный вывод: создайте таблицу для каждой сущности.

Gert Arnold is on strike 11.05.2023 16:49

Отвечает ли это на ваш вопрос? Как можно представить наследование в базе данных?

philipxy 11.05.2023 23:38

Вы можете смоделировать это как Table-Per-Hierachy с универсальным типом, о котором я писал в других ответах. Дайте мне знать, если вы хотите, чтобы я покопался и нашел пример.

Jeremy Lakeman 12.05.2023 03:58
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
52
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

на мой взгляд, вам лучше иметь таблицу документов и иметь таблицы, в которых указано, к какому документу это относится (PersonDocumet, CompanyDocumet, ItemDocument), чтобы вы могли иметь контроль.

когда вы вставляете данные, шаг 1: вставьте в документ, затем вставьте в другую таблицу

Документ: Идентификатор, URL

Документ человека:

идентификатор документа, PersonID


КомпанияДокумент:

идентификатор документа, Идентификатор компании


ТоварДокумент:

идентификатор документа, ID товара

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

Keith 11.05.2023 21:14

Поскольку вы работаете с устаревшей системой, вам необходимо убедиться, что существующая функциональность остается неизменной. Лучше иметь отдельные таблицы для каждого типа документа, хотя это может быть сложно для управления существующими данными. Другой способ справиться с этим сценарием — отдельные методы для вставки/обновления, связанные с (PersonDocument, CompanyDocument и ItemDocument), и вам необходимо вызывать методы, применяя бизнес-логику.

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