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

У меня в базе есть следующая схема:

  • BillingReferences (ReferencingType tinyint, ReferencingId tinyint, ReferencedType tinyint, ReferencedId tinyint, IsActive bit) - где все поля (кроме IsActive) являются частью уникального индекса.
  • BillingType (BillingTypeId tinyint, имя varchar (50))

ReferencingType и ReferencedType - это внешний ключ BillingTypes. BillingTypes содержит следующие строки:

BillingTypeId | Имя

1 | Этикетки

2 | Страны

3 | PaymentProviders

4 | Варианты оплаты

5 | банки

ReferecingId и ReferencedId представляют собой идентификатор одной из следующих сущностей (зависит от типа ссылки / ссылки):

  • Банки (BankId tinyint, имя varchar (50))
  • Страны (CountryId tinyint, имя varchar (50))
  • Ярлыки (LabelId tinyint, имя varchar (50))
  • PaymentProviders (PaymentProviderId tinyint, имя varchar (50))
  • PaymentOptions (PaymentOptionId tinyint, имя varchar (50))

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

Между всеми объектами (кроме стран) и странами существует связь (1- ). Ярлыки имеют связь (1-) с банками, поставщиками платежей и опциями оплаты. И у PaymentProvider есть соединение (1- *) с PaymentProvider.

Так, например, если я хочу подключить банк с BankId 201 к стране с CountryId 3003, у меня будет запись в BillingReferences, которая будет выглядеть так: ReferencingType = 5 ReferencingId = 201 ReferencedType = 2 ReferencedId = 3003 IsActive = 1

Мы не создали таблицу соединений / ссылок для каждого типа соединения из соображений расширяемости. Если мы хотим добавить еще одну сущность, все, что нам нужно сделать, это добавить ее таблицу и добавить записи для нее в BillingReferences и BillingType.

Проблема в том, что я не могу настроить условный внешний ключ между BillingReferences и каждым из объектов, и я не могу настроить / сопоставить его с EntityFramework ...

Мне не удалось найти ни одного учебника или примера, в котором используется этот тип реализации. Обязан ли я создавать справочную таблицу для каждого подключения или есть способ настроить это с помощью EntityFramework?

Спасибо за помощь :)


person Captain    schedule 03.03.2009    source источник


Ответы (5)


AFAIK, нет способа сделать это.

Я бы пошел с созданием отдельной таблицы для каждого типа, если у вас действительно нет веской причины не делать этого. То, что вы упомянули, нехорошее, ИМХО.

Наличие большего количества таблиц позволяет вам накладывать ограничения внешнего ключа на ваши ключи, и это хорошо транслируется в EF. Это также способствует повышению производительности: ваша большая справочная таблица с одним миллионом строк потребует больше времени для запроса, чем более мелкие таблицы (если вам ВСЕГДА не нужны все ссылки для типа).

person Inferis    schedule 03.03.2009
comment
если вам ВСЕГДА не нужны все ссылки для типа - более или менее ... Мне всегда нужно показывать, скажем, все страны, связанные с определенным банком, или все банки, связанные с определенным лейблом. Пользователь должен иметь возможность ассоциировать / деассоциировать любую сущность, которую он хочет, с выбранной сущностью. - person Captain; 03.03.2009

Это невозможно сделать не только в Entity Framework, но и в SQL. У вас не может быть внешнего ключа, который ссылается на одну из пяти разных таблиц.

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

person Craig Stuntz    schedule 03.03.2009
comment
Вы можете сказать, что у каждой сущности есть свои собственные специальные столбцы, я только что описал упрощенную версию ... Поэтому я не понимаю, как для меня подойдет Table Per Hierarchy Mapping ... - person Captain; 03.03.2009
comment
Составьте таблицу по типу, если это лучше для частей, которые вы не показываете в своем вопросе. Дело в том, что использование супертипа позволяет вам использовать реальный внешний ключ в БД, в результате чего EF предоставит вам нужное отображение. - person Craig Stuntz; 03.03.2009

Единственный способ добиться желаемого - это создать триггер для обработки обработки на стороне сервера. Вы не можете сопоставить такие FK с несколькими таблицами. Но триггер может справиться с этой логикой. Конечно, это было бы совершенно вне EF ...

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

person Jason Short    schedule 31.07.2009

Что ж, думаю, я воспользуюсь предложением Inferis и создам отдельную таблицу для каждого типа.

Спасибо, ребята, за ответы - они помогли ОЧЕНЬ :)

person Captain    schedule 03.03.2009

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

person MrDee    schedule 19.07.2017