Сопоставление связи с устаревшей базой данных с использованием Entity Framework CTP5

У меня возникли проблемы с сопоставлением двух объектов вместе с Entity Framework CTP5 с использованием Code First/Fluent API. База данных старая из другого приложения (Exact MAX), на которое переходит наша компания, и я пишу приложение для собственного использования для управления отгрузками на нашем складе. Ничего не сохраняется в старой базе данных, в которую входят объекты, упомянутые в этом посте.

Сущностями являются SalesOrder, у которых есть только один Address, и Address, у которых может быть много SalesOrders. Мне нужно указать имена столбцов, и это одна из проблем. Во-вторых, адрес имеет два ключа: идентификатор клиента и идентификатор адреса, которые связаны с соответствующими столбцами в SalesOrder. Имена столбцов ужасны: CUSTID_27 и SHPCDE_27 в таблице SO_Master для SalesOrders, CUSTID_24 и SHPCDE_24 в таблице SHIPPING_MASTER для адресов.

В конце концов я сдался прошлой ночью. Строки кода в этом сообщении взяты из карты для SalesOrder, а последние две части предназначены для сопоставления SalesOrder и Address. Для каждого ключа есть сопоставление, которое я собрал вместе из поиска Google, но я даже не уверен, что это нужно делать двумя отдельными проходами. Полученные записи Address сами по себе в порядке, а записи в SalesOrders — нет. Одна извлеченная запись SalesOrder имела допустимый адрес, но остальные SalesOrders имели нулевые адреса.

this.ToTable("SO_Master");

this.HasKey(so => so.Id);

this.Property(so => so.OrderDate).HasColumnName("ORDDTE_27");
this.Property(so => so.Id).HasColumnName("ORDNUM_27");

// Maps Customers
this
    .HasOptional(s => s.Customer)
    .WithMany(c => c.SalesOrders)
    .IsIndependent()
    .Map(m => m.MapKey(c => c.Id, "CUSTID_27"));

// Maps Address
this
    .HasOptional(s => s.Address)
    .WithMany(a => a.SalesOrders)
    .IsIndependent()
    .Map(m => m.MapKey(a => a.CustomerId, "CUSTID_27")); 

this
    .HasOptional(s => s.Address)
    .WithMany(a => a.SalesOrders)
    .IsIndependent()
    .Map(m => m.MapKey(a => a.Id, "SHPCDE_27"));

У меня не было бы проблем с использованием аннотаций данных, если это необходимо. Вместо этого я мог бы использовать LINQ to SQL, но я хотел бы посмотреть, есть ли решение, использующее это. Возможно, EF — не лучший выбор для этой базы данных, но код разделен достаточно хорошо, чтобы я мог поэкспериментировать. Я использую Visual Studio Express и SQL Server Express 2008 R2 и не смог найти ничего, что позволяло бы использовать конструкторы, поэтому я использую Code First.

Спасибо, что нашли время, чтобы прочитать этот пост.

Хорошо, в итоге я принял предложение Vulgarbinary использовать аннотации данных и просто использовал атрибуты ForeignKey там, где они были необходимы. Мне по-прежнему приходилось использовать Fluent API для сопоставления адреса с клиентом. Я не уверен, почему именно. Записи адресов продолжали возвращаться с пустыми клиентами без сопоставления Fluent API. Я думаю, потому что у меня есть два ключа в Address для привязки адресов к заказам, но только один для сопоставления клиентов с адресами.

this.HasRequired(a => a.Customer).WithMany().HasForeignKey(a => a.CustomerId);

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


person Apokryphos    schedule 22.02.2011    source источник


Ответы (1)


От SalesOrder до Address будет this.References(x => x.Address), и у вас будет отдельное поле для AddressID, чтобы вы могли сопоставить ассоциацию внешнего ключа и имя столбца.

В сопоставлении адресов у вас будет:

this.WithMany(x => x.SalesOrders)

В вашем фактическом POCO вам понадобится FK в SalesOrder POCO для Address и один Address POCO.

Итак, в классе SalesOrder:

Address Address {get;set;} 
int AddressID {get;set;}

Адрес класса:

List<SalesOrder> SalesOrders {get;set;}

Это должно сделать это за вас.

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

person VulgarBinary    schedule 22.02.2011
comment
Я, должно быть, забыл, насколько EF должен был облегчить вашу жизнь, когда я начал сопоставлять эту старую базу данных. Я перешел на аннотации, как вы предложили. Гораздо меньше работы, Entity Framework сделал большую часть сопоставления за меня. Ваш ответ не был решением, но он указал мне правильное направление и сэкономил мне время, поэтому я принимаю его. Спасибо! - person Apokryphos; 22.02.2011
comment
Он показал, что вам нужно сделать, чтобы исправить ваше сопоставление 1: M, и указал, что сопоставление EF Fluent требует слишком много работы. Если бы я сделал больше, я бы написал весь ваш код для вас ;-) Кроме того, я, вероятно, написал бы исправление беглого отображения, если бы вы опубликовали свои POCO и сопоставление для обоих классов. Кто угодно... Удачи! - person VulgarBinary; 23.02.2011