首页 > 解决方案 > 外键部署到 SQL 服务器的问题 - 代码优先 - 空外键

问题描述

我在 .NET 核心和 EF Core 3.0 中有休息 API,我遇到了一个奇怪的问题。下面是我的实体。

[Table(name: "BizObjects")]
public class BizObject
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
    [Required]
    [StringLength(06)]
    public int Id { get; set; }
    public string Category { get; set; } //FK

    [MaxLength(2)]
    public int ItemIncrement { get; set; }

    [MaxLength(2)]
    public int SubItemIncrement { get; set; }
    public virtual BizObjectT BizObjectT { get; set; }
}

[Table(name: "BizObjectsT")]
public class BizObjectT
{
    [StringLength(02)]
    public string Lang { get; set; }
    public string Text { get; set; }

    #region Primary Key derived from Foreign key for Config tabels                
    [Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
    [ForeignKey(name: "BizObjectId")]
    [Required]
    public int BizObjectId { get; set; }
    public virtual BizObject BizObject { get; set; }       
    #endregion
}

这是我的 DbContext。

public class ApplicationContext : DbContext, IDisposable
{
    public ApplicationContext(DbContextOptions options)
        : base(options: options) { }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<BizObject>()
            .HasOne<BizObjectT>(s => s.BizObjectT)
            .WithOne(g => g.BizObject)
            .HasForeignKey<BizObjectT>(s => s.BizObjectId);
    }

    public DbSet<BizObject> BizObjects { get; set; }
    public DbSet<BizObjectT> BizObjectsT { get; set; }
}

现在,这一切都很好。我能够创建迁移并将其部署到数据库。我的外键在 API 中正常工作。

但我得到的问题是 SQL 服务器。在这里,我无法在实现的关系窗口中找到外键主表。即使尝试手动添加 FK,我也看不到该表状态。

请参阅下面的快照。 在此处输入图像描述

我不确定问题出在哪里,任何建议都会有很大帮助。

谢谢。

更新 1:

这是实体生成的迁移。

public partial class initial : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.CreateTable(
            name: "BizObjects",
            columns: table => new
            {
                Id = table.Column<int>(maxLength: 6, nullable: false),
                Category = table.Column<string>(nullable: true),
                ItemIncrement = table.Column<int>(maxLength: 2, nullable: false),
                SubItemIncrement = table.Column<int>(maxLength: 2, nullable: false)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_BizObjects", x => x.Id);
            });

        migrationBuilder.CreateTable(
            name: "BizObjectsT",
            columns: table => new
            {
                BizObjectId = table.Column<int>(nullable: false),
                Lang = table.Column<string>(maxLength: 2, nullable: true),
                Text = table.Column<string>(nullable: true)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_BizObjectsT", x => x.BizObjectId);
                table.ForeignKey(
                    name: "FK_BizObjectsT_BizObjects_BizObjectId",
                    column: x => x.BizObjectId,
                    principalTable: "BizObjects",
                    principalColumn: "Id",
                    onDelete: ReferentialAction.Cascade);
            });
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropTable(
            name: "BizObjectsT");

        migrationBuilder.DropTable(
            name: "BizObjects");
    }
}

奇怪的是,如果我更改数据库名称,它将起作用。但仅适用于前几张桌子。

假设我有 10 个表在迁移中,这个BizObject是第一个表,然后在更改数据库名称后,SQL 将引用BizObject而不是其他表,这是随机的。

以供参考 :

休息 API 配置:

今天我将使用新版本的 SQL Server 和 SSMS 检查所有这些,稍后会在此处发布更新...

更新 2:

问题似乎出在 SQL Server 或 SSMS 上,因为我删除了几个表并运行了迁移,外键不起作用,但在关系表的下拉列表中,我可以看到我没有在迁移中添加的表名。

标签: c#sql-serverasp.net-coreef-fluent-apief-core-3.0

解决方案


你的FK注释不是关闭了吗?代替

[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
[ForeignKey(name: "BizObjectId")]
[Required]
public int BizObjectId { get; set; }
public virtual BizObject BizObject { get; set; } 

不应该是这样的:

[Required]
public int BizObjectId { get; set; }
[ForeignKey(name: "BizObjectId")]
public virtual BizObject BizObject { get; set; }

请参阅:EF 核心文档

我还删除了该[Key]属性,因为我很确定它不能同时是键和外键 - 如果您愿意,可以添加唯一索引。或者如果它确实用作 PK (1:1) 您应该删除该[DatabaseGenerated]属性,因为在子记录中它不能由 DB 生成。


推荐阅读