实体框架代码优先:如何在两个表之间创建一对多和一对一的关系?

时间:2011-03-18 00:39:38

标签: c# entity-framework entity-framework-ctp5

这是我的模特:

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; }
}

客户可以拥有任意数量的地址,但这些地址中只有一个可以是邮寄地址。

我可以获得One to One关系,而One to Many工作得很好,如果我只使用一个,但是当我尝试介绍两者时,我在Addresses表上获得了多个CustomerID键(CustomerID1,CustomerID2,CustomerID3)。我真的把头发撕成了这个。

为了映射One to One关系,我正在使用此处描述的方法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 个答案:

答案 0 :(得分:18)

我几乎整天都在努力解决这个问题,当然我等到最后才弄清楚这一点!

除了实现博客中所展示的一对一之外,我还需要使用流畅的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

答案 1 :(得分:2)

我知道你正试图找出实体框架这样做的方法,但如果我正在设计这个,我建议甚至不要将MailingAddress连接到数据库。只需将它设为这样的计算属性:

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