Entity Framework Code First: Как я могу создать связь "один-ко-многим" и "один-к-одному" между двумя таблицами?
Вот моя модель:
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
Ответы
Ответ 1
Я боролся с этим почти целый день, и, конечно, я жду, чтобы спросить здесь, прежде чем, наконец, понять это!
В дополнение к внедрению One to One, как показано в этом блоге, мне также понадобилось использовать беглое 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
Я знаю, что вы пытаетесь выяснить способ Entity Framework для этого, но если бы я это проектировал, я бы рекомендовал даже не подключать MailingAddress к базе данных. Просто сделайте это рассчитанным свойством следующим образом:
public MailingAddress {
get {
return Addresses.Where(a => a.IsPrimaryMailing).FirstOrDefault();
}
}