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

EF Core如何配置非主键且已有外键的列作为外键关联?

EF Code-First 创建外键关联时生成影子外键问题

简单数据库架构

我们已不再使用User表的自增ID列,改为在Resource表生成ID后,通过外键关联到User表。

采用EF Code-First方式生成迁移脚本及数据库架构时,尝试在UserInvite与User的ResourceId列间创建外键关联,但无论怎么操作,EF都会在User表中创建名为ResourceId1的影子外键属性,报错信息如下:

外键属性“User.ResourceId1”已在影子状态下创建,因为实体类型中存在一个名为“ResourceId”的冲突属性,但该属性未映射、已用于其他关系或与关联的主键类型不兼容。

这种外键关联可以在SSMS中正常创建,但无法通过Code-First实现。


实体定义

public class Resource
{
    public int Id { get; set; }
}
public class User
{
    public int Id { get; set; }

    public int ResourceId { get; set; }
    public Resource Resource { get; set; } = null!;
}
public class UserInvite
{
    public int Id { get; set; }
    public int? UserResourceId { get; set; }

    [ForeignKey("UserResourceId")]
    public User? User { get; set; }
}

已尝试的Fluent API写法

分别试过以下几种配置:

modelBuilder.Entity<UserInvite>()
    .HasOne(ui => ui.User)
    .WithMany()
    .HasPrincipalKey(u => u.ResourceId);

modelBuilder.Entity<User>()
    .HasMany<UserInvite>()
    .WithOne(ui => ui.User)
    .HasPrincipalKey(u => u.ResourceId);

modelBuilder.Entity<User>()
    .HasMany<UserInvite>()
    .WithOne(ui => ui.User)
    .HasPrincipalKey(u => u.ResourceId)
    .HasForeignKey(ui => ui.UserResourceId);

modelBuilder.Entity<UserInvite>()
    .HasOne(ui => ui.User)
    .WithMany()
    .HasPrincipalKey(u => u.ResourceId)
    .HasForeignKey(ui => ui.UserResourceId);

修改迁移脚本的尝试

修改迁移脚本后,插入记录时EF抛出异常,推测它默认期望用User.Id作为外键的主体列。

测试用实体定义:

public class Test
{
    public int Id { get; set; }
    public int? UserResourceId { get; set; }

    [ForeignKey(nameof(UserResourceId))]
    public User? User { get; set; }
}

已将迁移脚本中的principalColumn从Id改为ResourceId:

migrationBuilder.CreateTable(
    name: "UserInvite",
    columns: table => new
    {
        Id = table.Column<int>(type: "int", nullable: false)
            .Annotation("SqlServer:Identity", "1, 1"),
        UserResourceId = table.Column<int>(type: "int", nullable: true)
    },
    constraints: table =>
    {
        table.PrimaryKey("PK_Tests", x => x.Id);
        table.ForeignKey(
            name: "FK_Tests_Users_UserResourceId",
            column: x => x.UserResourceId,
            principalTable: "Users",
            principalColumn: "ResourceId");
    });

内容的提问来源于stack exchange,提问作者Jason Bert

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 01:55:19