2010-11-10 1 views
3

Я уже прочитал Entity Framework One-To-One Mapping Issues, и это не дублируется, так как здесь спецификация бизнес-правил различна.Ошибка One to One в Entity Framework 4

Существует две таблицы, счета-фактуры и ордера.

Invoices 
-> InvoiceID (Primary, Auto Number) 
Orders 
-> OrderID (Primary, Auto Number) 
-> InvoiceID (FK InvoiceID of Invoices Table) 

Теперь проблема заключается в том, что для этой ассоциации EF требует отношения «Один к многим», если имена свойств не совпадают. Если имена свойств одинаковы, то он служит назначению производного класса, но здесь Order не является производным классом или счетом-фактурой.

InvoiceID (ы) генерируются для каждой корзины покупок, но OrderID (ы) создаются только для платных счетов-фактур, поэтому каждый заказ имеет InvoiceID, но у каждого заказа нет соответствующего счета-фактуры.

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

Однако, в настоящее время, если я изменить модель, как следовать, она работает

Invoices 
-> InvoiceID (Primary, Auto Number) 
Orders 
-> OrderID (Auto Number) 
-> InvoiceID (Primary, FK InvoiceID of Invoices Table) 

Но это хорошая практика? Потому что по определению InvoiceID таблицы Orders, безусловно, будет уникальным, но мы будем ссылаться всюду на OrderID для сравнения и на множество других ссылок. Я знаю, что могу индексировать свойство, но я не чувствую, что этот дизайн идеален.

One to One Error

ответ

2

То, что кажется очевидным решение здесь является изменение 1: * связи между фактурой и порядком в EDM в 1: 1 ассоциацию. Однако, как вы это делали, сопоставление не будет подтвердите, если у вас есть Внешняя ассоциация ключей между двумя объектами, как в вашей модели.

Единственный способ отображения уникального внешнего ключа ассоциации заключается в использованииНезависимая ассоциация. Это тот же тип ассоциации, что и в EF3.5, где внешние ключи не поддерживались.

Включение ассоциации внешнего ключа в независимую ассоциацию означает удаление внешнего ключа InvoiceID из объекта Order и воссоздание ассоциации посредством сопоставлений.

Чтобы внести изменения в ассоциацию, вам необходимо сделать следующее:

  1. Удаление внешнего ключа свойства InvoiceID от объекта Order.
  2. Выберите Asscoation между фактурой и заказом.
  3. В окне «Свойства» для ассоциации откройте ссылочные ограничения на , щелкнув по эллипсам рядом с этим свойством.
  4. Удалите ограничение, нажав кнопку «Удалить».
  5. Щелкните правой кнопкой мыши ассоциацию в конструкторе и выберите «Отображение таблицы» в контекстном меню.
  6. В окне «Сведения о картографии» нажмите элемент , чтобы открыть раскрывающийся список.
  7. Из раскрывающегося списка выберите Заказ. Отображения должны заполняться автоматически.
  8. Вернитесь в окно «Свойства» для ассоциации.
  9. Для свойства «End2 Multiplicity», которое в настоящее время имеет значение * Collection of Orders, измените это свойство на 1 (One of Order), используя его раскрывающийся список.
  10. Подтвердите модель, щелкнув правой кнопкой мыши по поверхности дизайна и выбрав Validate. Вы увидите, что сообщение об ошибке, связанное с этим отображением, исчезло.

При возникновении этой проблемы в вашем приложении, вы должны решить, что более важно для вашей модели и логика приложения: внешний ключ скаляра (например, Order.InvoiceID) или быть в состоянии определить, связь 1: 1 между одним объектом (счет-фактура) и другим (заказ), когда они соединены через внешний ключ (InvoiceID).

Хорошая новость заключается в том, что новый EF4.0 Ленивая загрузка будет по-прежнему работать с независимыми ассоциациями, только внешний ключ не подвергается. Для того, чтобы получить, что вам придется перейти к свойству навигации (счета-фактуры) и прочитать его InvoiceID как код ниже:

Order order = context.Orders.First(); 
int invoiceID = order.Invoice.InvoiceID; 

Или вы можете использовать код, приведенный ниже, чтобы прочитать его прямо на предприятие порядка withought необходимости Lazy Load или Eager Load the Invoice:

int invoiceID = order.InvoiceReference.EntityKey.EntityKeyValues[0].Value; 
+0

Спасибо, быстрый вопрос, будет ли работать с навигацией, или это не сработает, если я сделаю это таким образом? –

+0

Нет проблем и, конечно же, они будут работать, я обновил свой ответ, чтобы показать вам два способа получить этот скрытый InvoiceId FK для Order Entity. –

+0

Спасибо за помощь. –