如何在EF中仅用标识符字段定义外键(无导航属性)
仅通过标识符字段在EF Core的OnModelCreating中定义外键
问题场景
我需要在C#的DB Context的OnModelCreating方法中,仅使用标识符字段来定义外键关系。目前看到的示例都默认实体类中包含导航属性,比如:
带导航属性的Answer实体:
public sealed class Answer { public long UserId { get; set; } public User User { get; set; } = null!; // 其他属性... }
对应的配置方式:
modelBuilder.Entity<Answer>(entity => { // 其他配置... entity.HasOne(d => d.User).WithMany(p => p.Answers) .HasForeignKey(d => d.UserId) .OnDelete(DeleteBehavior.ClientSetNull); });
但如果实体类只保留外键标识符字段、不包含导航属性(如下方的Answer类),该如何配置外键?
无导航属性的Answer实体:
public sealed class Answer { public long UserId { get; set; } // 其他属性... }
注:不考虑“添加导航属性后按示例操作”的方案
解决方案
根据EF Core的API,可以直接通过指定实体类型的方式完成配置,无需依赖导航属性,分两种场景处理:
1. 两端都无导航属性
如果User类也没有对应Answer的集合导航属性,直接在Answer的配置中指定关联的实体类型即可:
modelBuilder.Entity<Answer>(entity => { // 其他实体配置... entity.HasOne<User>() // 明确关联的主实体类型 .WithMany() // 表示主实体没有对应的集合导航属性 .HasForeignKey(answer => answer.UserId) // 指定外键字段 .OnDelete(DeleteBehavior.ClientSetNull); });
2. 主实体有集合导航属性,依赖实体无引用导航属性
如果User类中包含Answers集合导航属性,但Answer类不想加User引用属性,可以在User的配置中完成外键定义:
public sealed class User { public long Id { get; set; } public ICollection<Answer> Answers { get; set; } = new List<Answer>(); // 其他属性... } // OnModelCreating中的配置 modelBuilder.Entity<User>(entity => { // 其他实体配置... entity.HasMany(user => user.Answers) .WithOne() // 表示依赖实体没有对应的引用导航属性 .HasForeignKey(answer => answer.UserId) .OnDelete(DeleteBehavior.ClientSetNull); });
上述两种方式都不需要给Answer添加User导航属性,仅通过外键字段就能在数据库中创建正确的外键约束关系。
内容的提问来源于stack exchange,提问作者greenoldman
相关产品推荐
相关产品推荐

