You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否在EF Core中通过字符串关联松散关联的实体?

基于Name字段配置Person与BannedName的可选关联

领域模型定义

我们拥有Person(人员)和BannedName(禁用名称)两个实体,均存在于DbContext中,代码如下:

class Person
{
    public int Id { get; set; }
    public string Name { get; set; }

    // 可选关联
    public BannedName BannedName { get; set; }
}

class BannedName
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class GameDbContext : DbContext
{
    public DbSet<Person> People { get; set; }
    public DbSet<BannedName> BannedNames { get; set; }
}

示例数据

Person数据

IdName
1Bill
2Rodent

BannedName数据

IdName
1Rodent
2Clown

需求与期望

是否可以基于Name字段配置两者间的可选关联?期望执行以下查询代码时:

var personWithBannedName = _dbContext.People
    .Include(person => person.BannedName)
    .Single(person => person.Name == "Rodent");

能返回如下对象结构:

{ Id: 2, Name: "Rodent", BannedName: { Id: 1, Name: "Rodent" } }

选择该方案的理由

  1. 若在Person中存储IsNameBanned布尔值,需随名称变更同步状态,本数据模型无需维护额外状态;
  2. 使用GroupJoin不利于领域测试和领域类的派生属性,我们希望脱离EF Core进行模型与测试设置,示例代码如下:
var personWithBannedName = new Person
{
    Id = 1,
    Name = "Some Banned Name",
    BannedName = new BannedName
    {
        Id = 1,
        Name = "Some Banned Name"
    }
};

Assert.True(personWithBannedName.IsNameBanned);
  1. 我们有大量基于内存SQLite的单元测试,希望避免使用SQL Server特定方案(如视图技巧)。

解决方案

可以实现该需求,通过EF Core的Fluent API配置基于Name字段的可选关联即可。在GameDbContext的OnModelCreating方法中添加以下配置:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Person>()
        .HasOne(p => p.BannedName)
        .WithMany() // BannedName无需定义反向导航属性
        .HasForeignKey(p => p.Name) // 以Person的Name作为外键
        .HasPrincipalKey(bn => bn.Name) // 以BannedName的Name作为替代键
        .IsRequired(false); // 配置为可选关联
}

说明

  • 该配置将Person.Name与BannedName.Name建立关联,当Person的Name存在于BannedName列表中时,会自动关联对应的BannedName实体;
  • 配置兼容SQLite等内存数据库,无需依赖SQL Server特定功能;
  • 领域模型可脱离EF Core独立使用,满足单元测试需求,直接构造实体即可验证派生属性(如IsNameBanned)。

内容的提问来源于stack exchange,提问作者Ned Grady

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 20:55:20