オブジェクト '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'に依存しています。1つ以上のオブジェクトがこの列にアクセスするため、ALTER TABLE ALTER COLUMNレーティングは失敗しました。

問題は何ですか?


1
制約DF_Movies_Rating__48CFD27Eを削除して、フィールドのタイプを変更します
Joe Taras

@JoeTarasしかし、私はそれという名前の制約を作成したことがありません。それは何ですか?どこにありますか?
ジョーダンアックス

2
フィールドDBMSを作成すると、制約が自動的に作成されます。テーブル情報を展開すると、制約セクションにそれが表示されます。あなたが見つけるかどうか教えてください;)
Joe Taras

回答:


252

これを試して:

フィールドタイプを変更する前に、制約DF_Movies_Rating__48CFD27Eを削除してください。

制約は通常、DBMS(SQL Server)によって自動的に作成されます。

テーブルに関連付けられた制約を表示するには、オブジェクトエクスプローラーでテーブル属性を展開し、次に以下のようにカテゴリ制約を展開します。

テーブルの木

フィールドタイプを変更する前に、制約を削除する必要があります。


40
@ManirajSS:ALTER TABLE yourtable DROP CONSTRAINT DF_Movies_Rating__48CFD27E
Joe Taras

18
制約の作成のきっかけは何ですか?私はたくさん持っていて、本当に欲しくありません!
Simon Parker、

5
うーん、フレームワーク(Laravel)とdropColumnのDB移行を使用したい場合はどうすればよいですか?SQLサーバーによって自動生成された不思議な名前の制約を削除する方法がわかりません:(
JustAMartin

2
私は確信している:私はそれをdropedとフォルダの制約が空になると、私はアプリケーションを実行するか、呼び出したときにupdate-database、それは再び自分自身を再作成する私は、この問題を投稿:stackoverflow.com/questions/40267769/...
mshwf

2
SQLServerが制約を暗黙的に削除しないのはなぜですか?結局のところ、それは暗黙のうちに作成されました!
youcantryreachingme 2018年

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;

これらの最後の2つのステートメントを組み合わせて、列を変更し、1行で制約に名前を付けることができます(とにかく既存のテーブルである場合は、そうする必要があります)。


最初にすべての制約に名前を付けることで問題を回避する方法に関する情報を追加していただきありがとうございます。(つまり、ランダムに命名された制約をドロップする問題を回避します)
youcantryreachingme

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 2016

AlterColumnXのように、AlterColumnXのラッパー/拡張/オーバーロード関数を作成する場合、そのDropConstraintロジックをそこに含めることができます。また、テーブル名と列名を渡すことができるため、再度記述する必要はありません。
N73k 2017年

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
今私の人生を2度救った。両方とも、チェック制約を削除する必要があります。まず、最初のクエリを使用する必要があります。次に、SYS.DEFAULT_CONSTRAINTSテーブルにチェック制約が見つからなかったため、2番目のクエリを使用する必要があります。どうもありがとう!
日曜日

8

依存している列を削除しようとすると、次のようなエラーが発生します。

オブジェクト 'DF __ *'は列 ''に依存しています。

その列に依存する制約を次のように削除します:

ALTER TABLE TableName DROP CONSTRAINT dependent_constraint;

例:

メッセージ5074、レベル16、状態1、行1

オブジェクト ' DF__Employees__Colf__1273C1CD'は、列 'Colf'に依存しています。

メッセージ4922、レベル16、状態9、行1

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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.