Entity Framework Code First: Как я могу создать отношения «один ко многим» и «один к одному» между двумя таблицами? - PullRequest
19 голосов
/ 18 марта 2011

Вот моя модель:

public class Customer
{
    public int ID { get; set; }

    public int MailingAddressID { get; set; }
    public virtual Address MailingAddress { get; set; }

    public virtual ICollection<Address> Addresses { get; set; }
}

public class Address
{
    public int ID { get; set; }

    public int CustomerID { get; set; }
    public virtual Customer Customer { get; set; }
}

У клиента может быть любое количество адресов, однако только один из этих адресов может быть почтовым адресом.

Я могу заставить отношения «Один к одному» и «Один ко многим» работать нормально, если я использую только один, но когда я пытаюсь ввести оба, я получаю несколько ключей CustomerID (CustomerID1, CustomerID2, CustomerID3) в таблице адресов. Я действительно рву на себе волосы.

Для сопоставления отношений «один к одному» я использую описанный здесь метод http://weblogs.asp.net/manavi/archive/2011/01/23/associations-in-ef-code-first-ctp5-part-3-one-to-one-foreign-key-associations.aspx

Ответы [ 2 ]

18 голосов
/ 18 марта 2011

Я боролся с этим почти весь день, и, конечно, я жду, чтобы спросить здесь, прежде чем, наконец, выяснить это!

В дополнение к реализации «Один к одному», как показано в этом блоге, мне также нужно было использовать свободный API, чтобы указать «многие ко многим», поскольку одного соглашения было недостаточно при наличии отношения «один к одному».

modelBuilder.Entity<Customer>().HasRequired(x => x.PrimaryMailingAddress)
    .WithMany()
    .HasForeignKey(x => x.PrimaryMailingAddressID)
    .WillCascadeOnDelete(false);

modelBuilder.Entity<Address>()
    .HasRequired(x => x.Customer)
    .WithMany(x => x.Addresses)
    .HasForeignKey(x => x.CustomerID);

А вот и последняя модель в базе данных: enter image description here

2 голосов
/ 18 марта 2011

Я знаю, что вы пытаетесь найти способ Entity Framework сделать это, но если бы я проектировал это, я бы рекомендовал даже не подключать MailingAddress к базе данных.Просто сделайте это вычисляемым свойством как это:

public MailingAddress {
   get {
      return Addresses.Where(a => a.IsPrimaryMailing).FirstOrDefault();
   }
}
...