Платформа объекта many-many вопрос

Помогите EF n00b разработать его базу данных. У меня есть несколько компаний, которые производят несколько продуктов, таким образом, существуют many-many отношения между компаниями и продуктами. У меня есть промежуточная таблица, Company_Product, который связывает их.

Каждая комбинация компании/продукта имеет уникальный SKU. Например, виджеты Высшей точки имеют SKU 123, но виджеты Омеги имеют SKU 456. Я добавил SKU как поле в промежуточной таблице Company_Product.

EF генерировал модель с 1:* отношения между компанией и таблицами Company_Product и 1:* отношения между продуктом и таблицами Company_Product. Я действительно хочу a: отношения между компанией и продуктом. Но самое главное нет никакого способа получить доступ к SKU непосредственно из модели.

Я должен поместить SKU в его собственную таблицу и записать соединение, или есть ли лучший путь?

8
задан Sisiutl 2 July 2010 в 17:55
поделиться

1 ответ

Я только что протестировал это в новом проекте VS2010 (EFv4), чтобы убедиться, и вот что я обнаружил:

Когда ваша ассоциативная таблица в середине (Company_Product) имеет ТОЛЬКО 2 внешних ключа к другим таблицам (CompanyID и ProductID), а затем добавление всех трех таблиц в конструктор приводит к моделированию отношения «многие ко многим». Он даже не создает класс для таблицы Company_Product. У каждой компании есть коллекция продуктов, а у каждого продукта есть коллекция компаний.

Однако, если ваша ассоциативная таблица (Company_Product) имеет другие поля (например, SKU, собственный первичный ключ или другие описательные поля, такие как даты, описания и т. Д.), То разработчик моделей EF создаст отдельный класс, и он будет то, что вы уже видели.

Наличие класса посередине с отношениями 1: * для Компании и Продукта - неплохая вещь, и вы все равно можете получить нужные данные с помощью нескольких простых запросов.

// Get all products for Company with ID = 1
var q =
    from compProd in context.Company_Product
    where compProd.CompanyID == 1
    select compProd.Product;

Верно, не так просто перемещаться по взаимосвязям модели, когда, например, у вас уже есть загруженные объекты сущности, но для этого и нужен уровень данных. Инкапсулируйте запросы, которые получают нужные данные. Если вы действительно хотите избавиться от этого среднего класса Company_Product и иметь прямое представление «многие-ко-многим» в модели класса, вам придется разделить таблицу Company_Product, чтобы она содержала только 2 внешних ключа, и избавиться артикула.

На самом деле, я не должен говорить, что вы ДОЛЖНЫ это делать ... вы все равно можете внести некоторые правки в конструктор и настроить его таким образом. Я попробую и доложу.

ОБНОВЛЕНИЕ

Сохраняя артикул в таблице Company_Product (это означает, что моя модель EF имела 3 класса, а не 2; она создала класс Company_Payload с 1: * для двух других таблиц), я попытался добавить связь напрямую между Компанией и Продуктом. Я выполнил следующие шаги:

  • Щелкните правой кнопкой мыши класс компании в конструкторе
  • Добавить> Связь
  • Установите «Конец» слева на «Компания» (он уже должен быть)
  • Установите «Конец» справа от Продукта
  • Измените обе кратности на «* (Многие)»
  • . Свойства навигации должны быть названы «Продукты» и «Компании»
  • Нажмите OK.
  • Щелкните правой кнопкой мыши ассоциацию в модели> щелкните «Сопоставление таблиц»
  • В разделе «Добавить таблицу или представление» выберите «Company_Product»
  • Сопоставьте компанию -> ID (слева) до CompanyID (справа)
  • Сопоставить продукт -> ID (слева) с ProductID (справа)

Но это не работает. Это дает эту ошибку: Ошибка 3025: проблема при сопоставлении фрагментов, начиная со строки 175: необходимо указать сопоставление для всех ключевых свойств (Company_Product.SKU) таблицы Company_Product.

Таким образом, эта конкретная ассоциация недействительна, потому что она использует Company_Product в качестве таблицы, но не сопоставляет поле SKU с чем-либо.

Кроме того, пока я исследовал это, я наткнулся на этот лакомый кусочек «Лучшей практики» из книги Entity Framework 4.0 Recipies (обратите внимание, что для таблицы связи с дополнительными полями, помимо 2 FK, они относятся к дополнительным полям как "полезная нагрузка". В вашем случае SKU - это полезная нагрузка в Company_Product).

Передовая практика

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

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

(Из главы 2. Основы моделирования объектных данных, 2.4. Моделирование отношений «многие ко многим» с полезной нагрузкой)

Звучит как хороший совет. Тем более, что у вас уже есть полезная нагрузка (SKU).

33
ответ дан 5 December 2019 в 05:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: