EF 4.1 Code First - Отображение отношения один к одному с нестандартными именами столбцов - PullRequest
1 голос
/ 05 ноября 2011

Я знаю, что многие люди спрашивают об отношениях один-к-одному в EF 4.1, но я не могу найти ответ на эту проблему.

У меня есть следующие классы POCO:

public class Contact
{
    public decimal nCont_id { get; set; }

    public virtual WebsiteMembership WebsiteMembership { get; set; }
    //a bunch of other properties
}

public class WebsiteMembership
{
    public int WebsiteMembershipId { get; set; }

    public virtual Contact Contact { get; set; }
}

Первичный ключ членства на сайте (WebsiteMembershipId) также является внешним ключом, который ссылается на nCont_id контакта.

Я пытаюсь настроить это, используя свободный API:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    //This is being done because of the unconventional column names I have to live with
    modelBuilder.Conventions.Remove<NavigationPropertyNameForeignKeyDiscoveryConvention>();

    //bunch of other stuff
    modelBuilder.Entity<Contact>().ToTable("contacts");
    modelBuilder.Entity<Contact>().HasKey(b => b.nCont_id);
    modelBuilder.Entity<Contact>().HasOptional(b => b.WebsiteMembership).WithRequired(b => b.Contact).Map(b => b.MapKey("WebsiteMembershipId"));

    modelBuilder.Entity<WebsiteMembership>().ToTable("WebsiteMembership");
    modelBuilder.Entity<WebsiteMembership>().HasKey(b => b.WebsiteMembershipId);

}

Но я получаю исключение при попытке сделать:

var websiteMembership = context.WebsiteMemberships.Where(c => c.WebsiteMembershipId == 1645942).FirstOrDefault();

Исключение:

Указанная схема недействительна. Ошибки: (263,6): ошибка 0019: каждый имя свойства в типе должно быть уникальным. Имя свойства 'WebsiteMembershipId' уже определен.

Означает ли это, что я не могу установить тот же первичный ключ, что и внешний ключ в EF CodeFirst? Или я тут что-то не так делаю? Будет ли это работать, если первичный ключ не совпадает со столбцом внешнего ключа?

Совет очень ценится!

1 Ответ

3 голосов
/ 05 ноября 2011

Я думаю, что когда вы определяете это отображение ...

modelBuilder.Entity<Contact>()
    .HasOptional(b => b.WebsiteMembership)
    .WithRequired(b => b.Contact)
    .Map(b => b.MapKey("WebsiteMembershipId"));

... вы косвенно определяете, что является основным и что зависит от отношений.Очевидно, Contact является основным, потому что набор свойств WebsiteMembership является необязательным для Contact, его можно хранить без WebsiteMembership.Субъект WebsiteMembership на другой стороне имеет обязательную ссылку на Contact, что означает, что зависит от Contact.

принципала (Contact) это объект с первичным ключом, зависимый (WebsiteMembership) объект с внешним ключом.Таким образом, когда вы используете MapKey для установки имени WebsiteMembershipId столбца внешнего ключа, вы определяете столбец для таблицы WebsiteMembership, а не для Contact.Но WebsiteMembership уже имеет свойство под названием WebsiteMembershipId.(Я полагаю, что именно здесь EF жалуется, что " Имя свойства 'WebsiteMembershipId' уже определено .) В отношении один-ко-многим внешним ключом будет ContactId как отдельное свойствостолбца, и вы должны будете использовать HasForeignKey вместо MapKey. Но в отношении один к одному ясно, что внешний ключ является первичным ключом в то же время, поэтому вам не нужно определятьвнешний ключ вообще.

Короче говоря, просто удалите MapKey:

modelBuilder.Entity<Contact>()
    .HasOptional(b => b.WebsiteMembership)
    .WithRequired(b => b.Contact);

(Но теперь мне любопытно, можете ли вы определить отношения между intи decimal свойство или если вы получите следующую ошибку.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...