#entity-framework #orm #entity-framework-4 #database-schema #mapping-model
#entity-framework #orm #entity-framework-4 #база данных-схема #отображение-модель
Вопрос:
Есть ли способ предварительно сформировать следующие сопоставления (используя подход, ориентированный на базу данных):
Таблицы: (Определение таблиц с синтаксисом, подобным C #, только для удобства чтения)
table MainItems
{
column PK not-null unique int MainItemKey;
column string Name;
column string AspectAInfo;
column string AspectBInfo;
// 0 for A, 1 for B, 2 for both (Could be replaced with 2 boolean columns)
column not-null int AspectABOrBoth;
}
table AspectAMoreInfo
{
column PK not-null unique in AspectAMoreInfoKey;
column FK not-null int MainItemKey;
column string PayLoadA;
}
table AspectBMoreInfo
{
column PK not-null unique in AspectBMoreInfoKey;
column FK not-null int MainItemKey;
column double PayLoadB;
}
Объекты:
// Map to MainItems table if column AspectABOrBoth is 0 or 2
class TypeAItem
{
// Map to MainItemKey column
int TypeAItemKey { get; set; }
string Name { get; set; } // Map to Name column
// Navigation property to AspectAMoreInfo rows
List<TypeAMoreInfo> MoreInfo { get; set; }
// Navigation property to MainItems row when AspectABOrBoth is 2
TypeBItem OptionalInnerItemB { get; set; }
}
// Map to MainItems table if column AspectABOrBoth is 1 or 2
class TypeBItem
{
// Map to MainItemKey column
int TypeBItemKey { get; set; }
string Name { get; set; } // Map to Name column
// Navigation property to AspectBMoreInfo rows
List<TypeBMoreInfo> MoreInfo { get; set; }
}
// Map to AspectAMoreInfo table
class TypeAMoreInfo
{
// Map to AspectAMoreInfoKey column
int TypeAMoreInfoKey { get; set; }
// Navigation property to MainItems row when MainItems.AspectABOrBoth is 0 or 2
TypeAItem Owner { get; set; }
}
// Map to AspectBMoreInfo table
class TypeBMoreInfo
{
// Map to AspectBMoreInfoKey column
int TypeBMoreInfoKey { get; set; }
// Navigation property to MainItems row when MainItems.AspectABOrBoth is 1 or 2
TypeBItem Owner { get; set; }
}
Возможные направления, которые я рассмотрел, но предпочитаю не использовать, включают:
-
Определение 2 представлений над таблицей MainItems и сопоставление объектов с ними.
(Можно было бы использовать базовый тип с этим вместе с типом Table-Per-Concrete.) -
Добавление в таблицу MainItems 2 столбцов FK с возможностью обнуления, которые указывают на self (в ту же строку) вместо AspectABOrBoth column
(1 ненулевой, если основным элементом является AspectA, другой ненулевой, если основным элементом является AspectB.)
(Можно было бы использовать разделение таблицы с этим, на основе новых столбцов FK.)
Ответ №1:
Разделение таблицы на несколько объектов возможно при использовании:
- Разделение таблицы — требует, чтобы объект совместно использовал только ключ, и каждое другое свойство может быть сопоставлено только одному объекту.
- Наследование TPH — требуется, чтобы базовая сущность определяла ключевые и общие свойства. Вложенные объекты могут содержать другие свойства, но свойства не могут быть общими для вложенных объектов. Таблица должна содержать один или несколько специальных столбцов (определителей), которые будут определять, какой тип в иерархии наследования представляет запись. MSL не допускает никаких сложных выражений для дискриминатора. Комплексное условие может быть создано только как логическое и из всех условий.
Если я посмотрю на ваши таблицы, это не похоже на наследование. TableAItem
и TableBItem
не имеют никаких общих свойств. Вероятно, единственным общим элементом является key, что усложняет остальную часть вашего дизайна, потому что связь с обоими TableAMoreInfo
и TableBMoreInfo
будет создана с MainItem
(владельцем ключа), а не с дочерними элементами.
Представления выглядят более подходящими для решения этой проблемы, но view по умолчанию доступен только для чтения в EF, если вы не измените SSDL вручную.
Комментарии:
1. Могут быть общие свойства, такие как «Name», которые я только что добавил к примеру. Наследование TPH было бы отличным, за исключением того, что строка не может быть сопоставлена с двумя разными производными типами одновременно. Разделение таблицы с помощью условий невозможно, по крайней мере, не с помощью конструктора.
2. Это больше о том, «давайте попробуем, и вы увидите». Это непростой случай. Не все можно сопоставить с EF так, как вы хотите.
3. Я так и думал, сопоставление новых моделей с существующими схемами без нарушения существующих обычаев может быть сложной задачей.