entity framework5代码优先中的一对一和一对多关系

我试了整整一天才能搞定这个。 我学到了很多关于EF的Fluent API的知识(例如, 这是一篇优秀的文章),但是我没有成功。

我有三个实体:

public class Address { [Key] public virtual int AddressId { get; set; } public virtual string AddressString { get; set; } } public class User { [Key] public virtual int UserId { get; set; } public virtual ICollection
Addresses { get; set; } } public class House { [Key] public virtual int HouseId { get; set; } public virtual Address Address { get; set; } }

并尝试了HasMany, HasOptional, WithOptional, WithOptionalDependentWithOptionalPrincipial所有组合,我可以想到UserHouse

 protected override void OnModelCreating(DbModelBuilder modelBuilder) 

我无法让它发挥作用。 我认为应该清楚,我想要什么。 一个用户可能有多个地址(首先我要强制至少一个,但现在我会很高兴,如果用户可能有地址可选…)而一个房子只有一个地址 – 这是需要。 如果房子的地址被级联删除会很好。

我相信以下内容对您有用

 public class Address { public int AddressId { get; set; } public string AddressString { get; set; } } public class User { public int UserId { get; set; } public virtual ICollection
Addresses { get; set; } } public class House { public int HouseId { get; set; } public virtual Address Address { get; set; } } public class TestContext : DbContext { public DbSet
Addresses { get; set; } public DbSet Users { get; set; } public DbSet Houses { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity().HasMany(u => u.Addresses).WithMany(); modelBuilder.Entity().HasRequired(h => h.Address).WithOptional().Map(m => m.MapKey("AddressId")); } }

请注意,自己指定外键字段通常更好,这可以使您以后的生活更轻松。 如果您这样做,那么您可以选择重写House如下:

 public class House { public int HouseId { get; set; } public int AddressId { get; set; } public virtual Address Address { get; set; } } 

Convention将链接AddressId和Address。 如果您在House和Address之间有一对一的映射,您还可以在主键上链接它们:

 public class House { [ForeignKey("Address")] public int HouseId { get; set; } public virtual Address Address { get; set; } } 

您提到过您希望强制执行至少一个地址 – 这与一对多关系无法实现。 只有当用户只有一个地址时才能执行此操作,此时您可以在User类上添加所需的AddressId属性。

另一条评论 – 你在代码中虚拟了一切。 您只需要将导航属性设置为虚拟。

这样的事情怎么样:

强制执行House Address

 modelBuilder.Entity().HasRequired(d => d.Address); 

要在UserAddress之间创建一对多关系:

 modelBuilder.Entity().HasMany(u => u.Addresses).WithMany().Map(x => { x.MapLeftKey("UserId"); x.MapRightKey("AddressId"); x.ToTable("UserAddress"); }); 

这应该做的是创建一个名为UserAddress的表,将User映射到Address

或者,您可以自己为UserAddress创建POCO并修改有问题的表:

 public class UserAddress { [Key] public int UserAddressId { get; set; } public User User { get; set; } public Address Address { get; set; } } public User { ... public virtual ICollection UserAddresses { get; set; } ... } public Address { ... public virtual ICollection UserAddresses { get; set; } ... } 

然后,您需要以下内容以确保需要UserAddress

 modelBuilder.Entity().HasRequired(u => u.Address); modelBuilder.Entity().HasRequired(u => u.User);