EF Core Code First实现单表多外键关联同一键值表(SQL Server)
EF Core Code First 实现单键值表多列关联方案
1. 定义实体类
先创建键值表实体,不添加任何导航属性,只保留核心业务字段:
public class KeyValueStore { public int Id { get; set; } public string Key { get; set; } // 状态标识,比如"RequestSubmitted"、"Approved" public string Value { get; set; } // 状态显示文本 public string Category { get; set; } // 可选:用于区分不同类型状态(如"RequestStatus"、"EventStatus") }
再定义用户请求表实体,包含两个关联键值表的外键列:
public class UserRequest { public int Id { get; set; } public string RequestTitle { get; set; } // 两个外键列,关联KeyValueStore.Id public int RequestStatusId { get; set; } public int ApprovalStatusId { get; set; } // 单向导航属性:从UserRequest到KeyValueStore public KeyValueStore RequestStatus { get; set; } public KeyValueStore ApprovalStatus { get; set; } }
2. 在DbContext中配置关联关系
用Fluent API配置单向关联,明确外键约束,同时避免在KeyValueStore中生成反向导航属性:
public class AppDbContext : DbContext { public DbSet<KeyValueStore> KeyValueStores { get; set; } public DbSet<UserRequest> UserRequests { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { // 替换为你的数据库连接字符串 optionsBuilder.UseSqlServer("YourConnectionString"); } protected override void OnModelCreating(ModelBuilder modelBuilder) { // 配置KeyValueStore的主键和唯一索引 modelBuilder.Entity<KeyValueStore>() .HasKey(k => k.Id); modelBuilder.Entity<KeyValueStore>() .HasIndex(k => new { k.Category, k.Key }) .IsUnique(); // 确保同类别下的状态键唯一 // 配置RequestStatus关联 modelBuilder.Entity<UserRequest>() .HasOne(u => u.RequestStatus) .WithMany() // 不指定反向导航,避免KeyValueStore生成集合属性 .HasForeignKey(u => u.RequestStatusId) .OnDelete(DeleteBehavior.Restrict); // 根据业务需求设置删除行为 // 配置ApprovalStatus关联 modelBuilder.Entity<UserRequest>() .HasOne(u => u.ApprovalStatus) .WithMany() // 同样不指定反向导航 .HasForeignKey(u => u.ApprovalStatusId) .OnDelete(DeleteBehavior.Restrict); } }
3. 核心逻辑说明
- 单向关联设计:
WithMany()不带参数的写法,会告诉EF Core不需要在KeyValueStore中创建对应的导航集合,完全满足“键值表不添加导航属性”的要求。 - 外键约束控制:明确指定外键列和删除行为,避免EF自动生成默认的冗余字段。
- 查询使用示例:查询时可正常用
Include加载关联状态:var requests = await _context.UserRequests .Include(u => u.RequestStatus) .Include(u => u.ApprovalStatus) .ToListAsync();
4. 迁移与验证
执行迁移命令生成数据库结构:
Add-Migration AddKeyValueStoreRelations Update-Database
检查数据库表结构:UserRequests表会有RequestStatusId和ApprovalStatusId两个外键,均关联KeyValueStores表的Id列,且KeyValueStores表无任何反向关联字段。
内容的提问来源于stack exchange,提问作者TechTurtle
相关产品推荐
相关产品推荐

