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, WithOptionalDependent
和WithOptionalPrincipial
所有组合,我可以想到User
和House
在
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);
要在User
和Address
之间创建一对多关系:
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; } ... }
然后,您需要以下内容以确保需要User
和Address
:
modelBuilder.Entity().HasRequired(u => u.Address); modelBuilder.Entity ().HasRequired(u => u.User);
- Fluent NHibernate使用FluentMappings忽略ClassMap中的属性
- 你如何“真正”使用Newtonsoft.Json序列化循环引用对象?
- c# – 文本框是否有字符限制?
- 将Windows密钥按键发送到应用程序
- Dispatcher在Textchanged事件中的Messagebox.Show上抛出InvalidOperationException
- 如何使用带有ODP(Oracle.DataAccess)的>> prepared query <<更新CLOB字段中的数据?
- 带有可选参数的构造函数违反new()约束
- 在web.config中的appSettings中使用“&amp;”
- 我无法理解如何使用SendMessage或PostMessage调用