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

时间:2013-10-19 00:27:00

标签: sql sql-server database entity-framework entity-framework-4

基本上我在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_ 电影 _Rating__48CFD27E'取决于列'评级'。 ALTER TABLE ALTER COLUMN评级失败,因为一个或多个对象访问此列。

问题是什么?

9 个答案:

答案 0 :(得分:223)

试试这个:

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

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

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

Tree of your table

您必须在更改字段类型之前删除约束。

答案 1 :(得分:40)

这是tsql方式

 ALTER TABLE yourtable DROP CONSTRAINT constraint_name     -- DF_Movies_Rating__48CFD27E

为了完整起见,这只是将@Joe Taras的评论作为答案

答案 2 :(得分:38)

我将此添加为响应,以解释约束的来源。 我试着在评论中这样做,但很难在那里很好地编辑: - /

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

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

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;

您可以组合最后两个语句,以便更改列并在一行中命名约束(如果它是现有表格,则必须这样做)

答案 3 :(得分:19)

由于约束具有不可预测的名称,您可以编写特殊脚本( 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));    
}

答案 4 :(得分:6)

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

  

对象'DF __ *'取决于列''。

删除依赖于该列的约束:

ALTER TABLE TableName DROP CONSTRAINT dependent_constraint;

示例:

  

Msg 5074,Level 16,State 1,Line 1

     

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

     

Msg 4922,Level 16,State 9,Line 1

     

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

Drop Constraint(DF__Employees__Colf__1273C1CD):

ALTER TABLE Employees DROP CONSTRAINT DF__Employees__Colf__1273C1CD;

然后您可以删除列:

Alter Table TableName Drop column ColumnName

答案 5 :(得分:1)

解决方案:

打开数据库表 - &gt;扩展表 - &gt;扩展约束并看到这个

screenshot

答案 6 :(得分:1)

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__')

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

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

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

Blog

答案 7 :(得分:-1)

在从多个表中删除列时,我遇到以下默认约束错误。如果您需要更改列的数据类型,也会出现类似的问题。

对象“ DF_TableName_ColumnName”取决于列“ ColumnName”。

要解决此问题,我必须先使用以下查询删除所有这些约束

import { forkJoin, Observable, of } from "rxjs";
import { map } from "rxjs/operators";

let mainObs = of("main").pipe(map(res => ({ success: true, result: res })));

// creating a typed array helps preventing this problem early.
let listOfObservables: Observable<{ success: boolean; result: string }>[] = [
  mainObs
];

listOfObservables.push(createObs());
listOfObservables.push(createObs());

forkJoin(listOfObservables).subscribe(
  (res: { success: boolean; result: string }[]) => {
    console.log(res);
    console.log(res[0].success); // <== ok
  }
);

function createObs() {
  return of({ success: true, result: "dummy" });
}

此后,我删除了所有这些列(我的要求,在这个问题中未提及)

DECLARE @sql NVARCHAR(max)=''     
SELECT @SQL += 'Alter table ' + Quotename(tbl.name) + '  DROP constraint ' + Quotename(cons.name) + ';'
 FROM SYS.DEFAULT_CONSTRAINTS cons 
 JOIN   SYS.COLUMNS col ON col.default_object_id = cons.object_id
 JOIN   SYS.TABLES tbl ON tbl.object_id = col.object_id
 WHERE  col.[name] IN ('Column1','Column2')

--PRINT @sql
EXEC Sp_executesql @sql 

如果有人发现相同的问题,我会在这里发布。

快乐编码!

答案 8 :(得分:-2)

尝试运行迁移时遇到此错误 为了解决这个问题,我重新命名了该列并使用

重新生成了迁移
add-migration migrationname -force
包管理器控制台中的

。我当时能够运行

update-database

成功。