【问题标题】:Issue with foreign key deployment to SQL server - Code First - Empty foreign key外键部署到 SQL 服务器的问题 - 代码优先 - 空外键
【发布时间】:2019-11-20 07:47:04
【问题描述】:

我在 .NET Core 和 EF Core 3.0 中有 rest 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 而不是其他表和这是随机的。

供参考:

  • VS 2019 版本 16.3.0

  • SSMS 版本 14.0

  • SQL Server 2014 版本 12.0

Rest API 配置:

  • .NET CORE 3.0

  • EF Core 3.0

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

更新 2:

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

【问题讨论】:

  • 生成数据库的SQL脚本会有帮助
  • 迁移包含大脚本,此表仅供参考。
  • 您必须从脚本中提取相关位。具体来说,如何创建外键。 (在脚本中搜索相关的表名/外键名)。 3 个应用程序层(EF-> SQL Server-> SSMS)中的任何一个都可能是问题所在。检查 SQL 系统视图 (docs.microsoft.com/en-us/sql/relational-databases/tables/…) 也会有所帮助。
  • @Alex 我做到了,是的,我可以看到我所有的外键。它在那里,但我无法在关系窗口中看到它们,我也无法创建任何新的外键。
  • 你点击链接了吗?您可以发布查询的输出吗?

标签: c# sql-server asp.net-core ef-fluent-api ef-core-3.0


【解决方案1】:

你的 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 Core Doc

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

【讨论】:

  • “我很确定它不能同时是一个键和一个外键”,我有这个来自客户的奇怪要求。所以我必须..
  • 好吧,我只是不确定 EF 能否处理它
  • 我尝试了你建议的方式,没有运气。似乎问题出在 sql server 或 ssms
  • 您也可以尝试从 OnModelCreate 中删除代码吗?由于我认为您使用的是属性,因此没有必要(尽管迁移代码看起来不错)
【解决方案2】:

最后,我想我找到了根本原因。

那就是 SSMS。我已将我的 SQL 服务器和 SSMS 更新到最新版本,并且它开始正常工作。稍后将发布更多更新...

【讨论】:

    猜你喜欢
    • 2015-02-24
    • 2022-01-01
    • 2018-02-13
    • 2011-08-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多