【问题标题】:Unable to delete FK from model code-first无法先从模型代码中删除 FK
【发布时间】:2017-06-21 19:18:57
【问题描述】:

我已经使用代码优先方法和现有数据库创建了一个 MVC 应用程序。

我注意到我的一个表不需要外键,所以我试图删除它,但我不断收到:

对象“FK_BorrowedProperty_codeStatus”依赖于列“StatusId”。 ALTER TABLE DROP COLUMN StatusId 失败,因为一个或多个对象访问此列。

我已经完成的步骤

  • 进入BorrowedProperty类并删除public int StatusId { get; set; }public virtual codeStatu codeStatu { get; set; }
  • 进入CodeStatu类并删除[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] public virtual ICollection<BorrowedProperty> BorrowedProperties { get; set; }
  • 进入我的 DbContext 并注释掉这一行 //modelBuilder.Entity<codeStatu>() // .HasMany(e => e.BorrowedProperties) // .WithRequired(e => e.codeStatu) // .HasForeignKey(e => e.StatusId) // .WillCascadeOnDelete(false);
  • 添加迁移 DeleteStatusFKFromBorrowedProperty

结果:

public partial class DeleteStatusFKFromBorrowedProperty : DbMigration
{
    public override void Up()
    {
        DropForeignKey("dbo.BorrowedProperty", "StatusId", "dbo.codeStatus");
        DropIndex("dbo.BorrowedProperty", new[] { "StatusId" });
        DropColumn("dbo.BorrowedProperty", "StatusId");
    }

    public override void Down()
    {
        AddColumn("dbo.BorrowedProperty", "StatusId", c => c.Int(nullable: false));
        CreateIndex("dbo.BorrowedProperty", "StatusId");
        AddForeignKey("dbo.BorrowedProperty", "StatusId", "dbo.codeStatus", "Id");
    }
}
  • 更新数据库

然后我收到上面的错误。 BorrowedProperty 数据库表中有 条记录。

我做错了什么?

【问题讨论】:

    标签: c# asp.net-mvc entity-framework entity-framework-migrations


    【解决方案1】:

    从异常消息中可以清楚地看出,您有一个名为 FK_BorrowedProperty_codeStatus 的外键约束,这会阻止删除 StatusId 列。您可以创建一个包含 SQL 命令的方法来删除 FK 约束,如下所示:

    private void DropForeignKeyConstraint()
    {
        // This command may work if the constraint name is known:
        // Sql(@"ALTER TABLE [dbo].[BorrowedProperty] DROP CONSTRAINT [FK_BorrowedProperty_codeStatus]");
    
        Sql(@"DECLARE @constraint NVARCHAR(128)
            SELECT @constraint = name
            FROM sys.default_constraints
            WHERE parent_object_id = object_id(N'dbo.BorrowedProperty')
            AND col_name(parent_object_id, parent_column_id) = 'StatusId';
            IF @constraint IS NOT NULL
               EXECUTE('ALTER TABLE [dbo].[BorrowedProperty] DROP CONSTRAINT [' + @constraint + ']')");
    }
    

    将方法放在Up 方法中的迁移代码中,如下所示:

    public partial class DeleteStatusFKFromBorrowedProperty : DbMigration
    {
        public override void Up()
        {
            DropForeignKeyConstraint(); // dropping FK constraint first
            DropForeignKey("dbo.BorrowedProperty", "StatusId", "dbo.codeStatus");
            DropIndex("dbo.BorrowedProperty", new[] { "StatusId" });
            DropColumn("dbo.BorrowedProperty", "StatusId"); // drop column at last
        }
    }
    

    或者,如果您有权访问 SSMS 实例,请直接运行此查询:

    ALTER TABLE [dbo].[BorrowedProperty] DROP CONSTRAINT [FK_BorrowedProperty_codeStatus]
    

    注意:您可以尝试注释掉 Down 方法中的所有代码行,以查看是否没有重新创建外键约束。

    之后,您可以在 Package Manager Console 中执行 Add-MigrationUpdate-Database 以应用上述更改。

    类似问题:

    The object 'DF__*' is dependent on column '*' - Changing int to double

    How do I drop a column with object dependencies in SQL Server 2008?

    Entity Framework Migrations can't drop table because of foreign key constraint

    【讨论】:

    • 好的,我确实可以访问我使用的 SSMS 实例,但我想知道方法解决方案.. 我是否必须在特定区域创建它(如在 migration.cs 中)或者我可以把它放在任何地方,然后在 migration.cs 中引用它?
    • 我直接使用了查询:ALTER TABLE [dbo].[BorrowedProperty] DROP CONSTRAINT [FK_BorrowedProperty_codeStatus] 并且运行良好
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-29
    • 1970-01-01
    • 2012-01-22
    • 1970-01-01
    • 1970-01-01
    • 2014-11-24
    • 1970-01-01
    相关资源
    最近更新 更多