วัตถุ 'DF __ *' ขึ้นอยู่กับคอลัมน์ '*' - การเปลี่ยน int เป็นสองเท่า


170

โดยทั่วไปฉันได้รับตารางในฐานข้อมูล 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; }

มันทำงานได้ดี แต่เมื่อฉันเปลี่ยน int ของการให้คะแนนเป็นสองเท่าฉันได้รับข้อผิดพลาดต่อไปนี้เมื่ออัปเดตฐานข้อมูล:

วัตถุ 'DF_ Movies _Rating__48CFD27E' ขึ้นอยู่กับคอลัมน์ 'การให้คะแนน' ALTER TABLE ALTER COLUMN การจัดอันดับล้มเหลวเนื่องจากวัตถุหนึ่งรายการขึ้นไปเข้าถึงคอลัมน์นี้

มีปัญหาอะไร


1
ลบข้อ จำกัด DF_Movies_Rating__48CFD27E แล้วเปลี่ยนประเภทของฟิลด์ของคุณ
Joe Taras

@ JoeTaras แต่ฉันไม่เคยสร้างข้อ จำกัด ชื่อนั้นมาก่อน มันคืออะไรและฉันจะหาได้ที่ไหน
Jordan Axe

2
เมื่อคุณสร้างเขตข้อมูล DBMS จะสร้างข้อ จำกัด โดยอัตโนมัติ หากคุณขยายข้อมูลตารางของคุณในส่วนข้อ จำกัด คุณจะพบมัน บอกฉันว่าคุณจะเจอ;)
Joe Taras

คำตอบ:


253

ลองสิ่งนี้:

ลบข้อ จำกัดDF_Movies_Rating__48CFD27Eก่อนที่จะเปลี่ยนประเภทฟิลด์ของคุณ

โดยทั่วไปจะสร้างข้อ จำกัด โดยอัตโนมัติโดย DBMS (SQL Server)

หากต้องการดูข้อ จำกัด ที่เกี่ยวข้องกับตารางให้ขยายแอ็ตทริบิวต์ตารางในObject explorerตามด้วยข้อ จำกัดหมวดหมู่ดังแสดงด้านล่าง:

ต้นไม้ของตารางของคุณ

คุณต้องลบข้อ จำกัด ก่อนที่จะเปลี่ยนประเภทฟิลด์


40
@ManirajSS: แก้ไขตาราง yourtable DROP CONSTRAINT DF_Movies_Rating__48CFD27E
Joe Taras

18
สิ่งที่กระตุ้นให้เกิดการสร้างข้อ จำกัด ? ฉันมีพวงของพวกเขาและฉันไม่ต้องการพวกเขา!
Simon Parker

5
อืมและจะทำอย่างไรถ้าฉันต้องการใช้การย้ายฐานข้อมูลของกรอบงาน (Laravel) และ dropColumn ที่นั่น ฉันไม่รู้ว่าจะทิ้งข้อ จำกัด ที่มีชื่อลึกลับที่สร้างอัตโนมัติโดยเซิร์ฟเวอร์ SQL :(
JustAMartin

2
ฉันแน่ใจว่า: ฉันวางมันลงและโฟลเดอร์ข้อ จำกัด จะว่างเปล่าและเมื่อฉันเรียกใช้แอปพลิเคชันหรือเรียกupdate-databaseมันสร้างขึ้นอีกครั้งฉันโพสต์ปัญหานี้: stackoverflow.com/questions/40267769/…
mshwf

2
ทำไม heck จึงไม่ SQLServer วางข้อ จำกัด โดยปริยาย? มันทำหลังจากทั้งหมดสร้างมันโดยปริยาย!
youcantryreachingme

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 ข้อความสุดท้ายเหล่านั้นเพื่อให้คุณเปลี่ยนคอลัมน์และตั้งชื่อข้อ จำกัด ในหนึ่งบรรทัด (คุณต้องทำถ้ามันเป็นตารางที่มีอยู่แล้ว)


ขอขอบคุณที่เพิ่มข้อมูลเกี่ยวกับวิธีหลีกเลี่ยงปัญหานี้โดยการตั้งชื่อข้อ จำกัด ทั้งหมดตั้งแต่แรก (นั่นคือหลีกเลี่ยงปัญหาของการปล่อยข้อ จำกัด ที่มีชื่อแบบสุ่ม)
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));    
}

คำตอบนี้ใช้ได้ดีในสภาพแวดล้อมที่ใช้การย้ายข้อมูลซึ่งคุณไม่สามารถกำหนดชื่อ hardcode ได้
Menion Leah

หากคุณสร้างฟังก์ชั่น wrapper / extension / overloaded สำหรับ 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__')

เพียงแทนที่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

บล็อก


1
ช่วยชีวิตฉันตอนนี้สองครั้ง ทั้งคู่ต้องลบข้อ จำกัด การตรวจสอบ ก่อนอื่นฉันต้องใช้แบบสอบถามแรก ประการที่สองฉันต้องใช้แบบสอบถามที่สองเพราะไม่พบข้อ จำกัด การตรวจสอบในตาราง SYS.DEFAULT_CONSTRAINTS ขอบคุณมาก!
วันอาทิตย์ที่

8

เมื่อเราพยายามที่จะวางคอลัมน์ซึ่งขึ้นอยู่กับแล้วเราจะเห็นข้อผิดพลาดประเภทนี้:

วัตถุ 'DF __ *' ขึ้นอยู่กับคอลัมน์ ''

ปล่อยข้อ จำกัด ซึ่งขึ้นอยู่กับคอลัมน์นั้นด้วย:

ALTER TABLE TableName DROP CONSTRAINT dependent_constraint;

ตัวอย่าง:

ข้อความเกี่ยวกับ 5074 ระดับ 16 สถานะ 1 บรรทัด 1

วัตถุ ' DF__Employees__Colf__1273C1CD'ขึ้นอยู่กับคอลัมน์ 'Colf'

ข้อความเกี่ยวกับ 4922 ระดับ 16 สถานะ 9 บรรทัด 1

การเปลี่ยนแปลงตาราง DROP COLUMN ล้มเหลวเนื่องจากวัตถุหนึ่งรายการขึ้นไปเข้าถึงคอลัมน์นี้

วางข้อ จำกัด (DF__Employees__Colf__1273C1CD):

ALTER TABLE Employees DROP CONSTRAINT DF__Employees__Colf__1273C1CD;

จากนั้นคุณสามารถวางคอลัมน์:

Alter Table TableName Drop column ColumnName

1

สารละลาย :

เปิดฐานข้อมูลตาราง -> ขยายตาราง -> ขยายข้อ จำกัด และดูสิ่งนี้

ภาพหน้าจอ


ในขณะที่รหัสนี้อาจตอบคำถาม แต่มีบริบทเพิ่มเติมเกี่ยวกับสาเหตุและ / หรือวิธีการที่รหัสนี้ตอบคำถามช่วยปรับปรุงมูลค่าระยะยาว
Donald Duck

-1

ฉันมีข้อผิดพลาดนี้พยายามเรียกใช้การโยกย้ายเพื่อแก้ไขมันฉันเปลี่ยนชื่อคอลัมน์และสร้างการโยกย้ายอีกครั้งโดยใช้

add-migration migrationname -force

ในคอนโซลตัวจัดการแพคเกจ ฉันสามารถวิ่งได้

update-database

ประสบความสำเร็จ


2
ระวังนี่จะไม่เปลี่ยนชื่อคอลัมน์เพราะมันจะทำให้คอลัมน์ลดลงและเพิ่มคอลัมน์ใหม่ คุณจะสูญเสียข้อมูลใด ๆ ที่เคยมีอยู่ในคอลัมน์เว้นแต่ว่าคุณจะเพิ่มรหัสที่กำหนดเองในการย้ายข้อมูล
caesay
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.