对象'DF __ *'依赖于列'*'-将int更改为double


168

基本上,我的EF数据库中有一个具有以下属性的表:

public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string Image { get; set; }
public string WatchUrl { get; set; }
public int Year { get; set; }
public string Source { get; set; }
public int Duration { get; set; }
public int Rating { get; set; }
public virtual ICollection<Category> Categories { get; set; }

它工作正常,但是当我将Rating的int更改为double时,在更新数据库时出现以下错误:

对象“ DF_ Movies _Rating__48CFD27E”取决于列“ Rating”。ALTER TABLE ALTER COLUMN评级失败,因为一个或多个对象访问此列。

怎么了


1
删除约束DF_Movies_Rating__48CFD27E,然后更改字段的类型
Joe Taras

@JoeTaras但是我从未创建过一个名为that的约束。这是什么,在哪里可以找到?
约旦斧头

2
创建字段DBMS时,将自动创建约束。如果您扩展表格信息,则在约束部分中会找到它。告诉我您是否可以找到;)
乔·塔拉斯

Answers:


252

试试这个:

在更改字段类型之前,请删除约束DF_Movies_Rating__48CFD27E

该约束通常由DBMS(SQL Server)自动创建。

要查看与表相关联的约束,请在“ 对象资源管理器”中展开表属性,然后展开“ 约束 ”类别,如下所示:

桌子上的树

您必须先删除约束,然后再更改字段类型。


40
@ManirajSS:更改表yourtable DROP CONSTRAINT DF_Movies_Rating__48CFD27E
Joe Taras

18
是什么触发了约束的产生?我有一堆,我真的不想要它们!
西蒙·帕克

5
嗯,如果我想使用我的框架(Laravel)和dropColumn的数据库迁移怎么办?我不知道如何删除由SQL Server自动生成的具有神秘名称的约束条件:(
JustAMartin

2
我确定:我放了它,并且文件夹Constraints变空了,当我运行应用程序或调用update-database它时,它再次重新创建了自己,我发布了这个问题:stackoverflow.com/questions/40267769/…–
mshwf

2
为什么SQLServer不会隐式删除约束?毕竟,它确实是隐式创建的!
youcantryreachingme '18 -10-3

46

这是tsql这样

 ALTER TABLE yourtable DROP CONSTRAINT constraint_name     -- DF_Movies_Rating__48CFD27E

为了完整起见,这仅显示@Joe Taras的评论作为答案


46

我将其添加为响应以解释约束的来源。我试图在评论中做到这一点,但是很难在其中很好地编辑:-/

如果创建(或更改)具有默认值的列的表,它将为您创建约束。

例如,在您的表中,它可能是:

CREATE TABLE Movie (
    ...
    rating INT NOT NULL default 100
)

它将为默认值100创建约束。

如果您改为像这样创建它

CREATE TABLE Movie (
  name VARCHAR(255) NOT NULL,
  rating INT NOT NULL CONSTRAINT rating_default DEFAULT 100
);

然后,您将得到一个命名良好的约束,当您更改所述表时,该约束更易于引用。

ALTER TABLE Movie DROP CONSTRAINT rating_default;
ALTER TABLE Movie ALTER COLUMN rating DECIMAL(2) NOT NULL;
-- sets up a new default constraint with easy to remember name
ALTER TABLE Movie ADD CONSTRAINT rating_default DEFAULT ((1.0)) FOR rating;

您可以合并最后两个语句,以便更改列并在一行中命名约束(无论如何,它必须是现有表)


感谢您添加有关如何通过首先命名所有约束来避免此问题的信息。(也就是说,避免掉落随机命名的约束的问题)
youcantryreachingme '18

22

由于约束具有不可预测的名称,因此您可以编写特殊脚本(DropConstraint)以在不知道其名称的情况下将其删除(已在EF 6.1.3中进行了测试):

public override void Up()
{    
    DropConstraint();
    AlterColumn("dbo.MyTable", "Rating", c => c.Double(nullable: false));
}

private void DropConstraint()
{
    Sql(@"DECLARE @var0 nvarchar(128)
          SELECT @var0 = name
          FROM sys.default_constraints
          WHERE parent_object_id = object_id(N'dbo.MyTable')
          AND col_name(parent_object_id, parent_column_id) = 'Rating';
          IF @var0 IS NOT NULL
              EXECUTE('ALTER TABLE [dbo].[MyTable] DROP CONSTRAINT [' + @var0 + ']')");
}

public override void Down()
{            
    AlterColumn("dbo.MyTable", "Rating", c => c.Int(nullable: false));    
}

这个答案在基于迁移的环境中非常有用,在这种环境中,您不能对约束名称进行硬编码。
Menion Leah

如果为AlterColumn创建包装器/扩展名/重载函数(如AlterColumnX),则可以在其中包含DropConstraint逻辑,并且可以传入表名和列名,因此不必再次编写它们。
N73k

10

MS SQL Studio会在您删除列时照顾您,但是如果您需要以编程方式删除约束,这里提供的是简单的解决方案

这是一个代码片段,它将删除具有默认约束的列:

DECLARE @ConstraintName nvarchar(200)
SELECT @ConstraintName = Name FROM SYS.DEFAULT_CONSTRAINTS WHERE PARENT_OBJECT_ID = OBJECT_ID('__TableName__') AND PARENT_COLUMN_ID = (SELECT column_id FROM sys.columns WHERE NAME = N'__ColumnName__' AND object_id = OBJECT_ID(N'__TableName__'))
IF @ConstraintName IS NOT NULL
EXEC('ALTER TABLE __TableName__ DROP CONSTRAINT ' + @ConstraintName)
IF EXISTS (SELECT * FROM syscolumns WHERE id=object_id('__TableName__') AND name='__ColumnName__')
EXEC('ALTER TABLE __TableName__ DROP COLUMN __ColumnName__')

只需将TableNameColumnName替换为适当的值即可。即使已删除该列,也可以安全地运行它。

奖励:这是删除外键和其他类型约束的代码。

IF EXISTS(SELECT 1 FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE where TABLE_NAME = '__TableName__' AND COLUMN_NAME = '__ColumnName__')
BEGIN
SELECT @ConstraintName = CONSTRAINT_NAME FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE where TABLE_NAME = '__TableName__' AND COLUMN_NAME = '__ColumnName__'
EXEC('ALTER TABLE __TableName__ DROP CONSTRAINT ' + @ConstraintName)
END

博客


1
现在救了我两次命。两者都必须删除检查约束。首先,我必须使用第一个查询。第二,我必须使用第二个查询,因为在SYS.DEFAULT_CONSTRAINTS表中找不到检查约束。非常感谢!
星期日

8

当我们尝试删除一个依赖的列时,我们会看到这种错误:

对象“ DF __ *”依赖于列“”。

通过以下方式删除依赖于该列的约束:

ALTER TABLE TableName DROP CONSTRAINT dependent_constraint;

例:

消息5074,第16级,状态1,第1行

对象' DF__Employees__Colf__1273C1CD'依赖于列'Colf'。

Msg 4922,第16级,状态9,第1行

ALTER TABLE DROP COLUMN Colf失败,因为一个或多个对象访问此列。

掉落约束(DF__Employees__Colf__1273C1CD):

ALTER TABLE Employees DROP CONSTRAINT DF__Employees__Colf__1273C1CD;

然后,您可以删除列:

Alter Table TableName Drop column ColumnName

1

解决方案:

打开数据库表->展开表->展开约束并查看

屏幕截图


尽管此代码可以回答问题,但提供有关此代码为何和/或如何回答问题的其他上下文,可以改善其长期价值。
唐老鸭

-1

我在尝试运行迁移以解决该错误时遇到了错误,我重命名了该列并使用重新生成了迁移

add-migration migrationname -force

在软件包管理器控制台中。然后我就可以跑步

update-database

成功。


2
请注意,这不会重命名列-它会删除该列并添加一个新列。除非您在迁移中添加自定义代码,否则您将丢失该列中曾经存在的任何数据。
caesay
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.