如何使用Fluent API创建Area与Location的简单一对多关系
问题解答与正确配置方案
1. 关于是否需要修改自动生成文件的最优方案
你生成的Area和Location都是partial类,完全不需要修改自动生成的原文件,只要新增两个同名的partial类文件存放自定义内容即可,重新执行Database First生成代码时不会覆盖你新增的内容:
// 新建文件Area.Extended.cs,不用修改原自动生成的Area.cs public partial class Area { // 导航属性放这里 public virtual ICollection<Location> Locations { get; set; } }
// 新建文件Location.Extended.cs,不用修改原自动生成的Location.cs public partial class Location { // 导航属性放这里,原文件的AreaId不要注释!要保留 public virtual Area Area { get; set; } }
注意:你之前把
Location.cs里的AreaId注释掉是错误操作,请改回原有代码,外键字段必须保留。
2. 各疑问的明确解答
- 关于是否需要在
Area中加Location集合引用:如果你的业务不需要从Area对象侧直接查询关联的所有Location,可以不加,WithMany直接留空参数即可;如果需要该导航属性,按上面的partial类方式添加即可,不用碰自动生成文件。 - 关于
WithMany的参数:如果你已经添加了Area.Locations导航属性,参数填a => a.Locations即可;如果没加,直接写.WithMany()无参即可。 - 关于是否需要用
[ForeignKey]特性:如果你用Fluent API配置关联,完全不需要加任何特性,所有规则都可以在OnModelCreating里统一配置,避免污染实体类。 - 关于你最后提到的如何指定
Location.AreaId关联Area.Id:你之前的HasForeignKey参数写错了,你填的是导航属性l => l.Area,实际应该填外键字段l => l.AreaId。EF默认会自动关联到目标实体的主键(你已经配置了Area的主键是Id),不需要额外指定关联目标字段。
3. 符合你需求的最终Fluent API配置
protected override void OnModelCreating(DbModelBuilder modelBuilder) { // 主键配置(如果自动生成的模型已经有主键配置,可以删掉这两行) modelBuilder.Entity<Area>().HasKey(t => t.Id); modelBuilder.Entity<Location>().HasKey(t => t.Id); // 外键关联配置 modelBuilder.Entity<Location>() // 指定Location必须关联Area(对应你要求的禁止删除被引用的Area,EF默认required外键的删除行为是Restrict,删除关联Area时会直接抛出异常) .HasRequired(l => l.Area) // 对应Area侧的导航属性,如果没加就直接写.WithMany() .WithMany(a => a.Locations) // 指定外键字段是Location.AreaId,EF会自动关联到Area的主键Id .HasForeignKey(l => l.AreaId) // 可选:显式指定删除行为,和默认行为一致,只是更明确 .WillCascadeOnDelete(false); }
以上配置完全满足你的三个需求:
Location.AreaId关联Area.Id、一个Area对应多个Location、禁止删除被关联的Area。
内容的提问来源于stack exchange,提问作者Dominique
相关产品推荐
相关产品推荐

