Đối tượng 'DF __ *' phụ thuộc vào cột '*' - Thay đổi int thành gấp đôi


168

Về cơ bản tôi đã có một bảng trong cơ sở dữ liệu EF của mình với các thuộc tính sau:

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; }

Nó hoạt động tốt tuy nhiên khi tôi thay đổi int của Xếp hạng thành gấp đôi, tôi gặp lỗi sau khi cập nhật cơ sở dữ liệu:

Đối tượng 'DF_ Phim _Rating__48CFD27E' phụ thuộc vào cột 'Xếp hạng'. ALTER TABLE ALTER COLUMN Xếp hạng không thành công vì một hoặc nhiều đối tượng truy cập vào cột này.

Vấn đề là gì?


1
Xóa các ràng buộc DF_Movies_Rating__48CFD27E và sau đó thay đổi loại trường của bạn
Joe Taras

@JoeTara Nhưng tôi chưa bao giờ tạo ra một ràng buộc có tên đó. Nó là gì và tôi tìm thấy nó ở đâu?
Jordan Axe

2
Khi bạn tạo một trường DBMS sẽ tự động tạo một ràng buộc. Nếu bạn mở rộng thông tin bảng của mình, trong phần ràng buộc bạn sẽ tìm thấy nó. Hãy cho tôi biết nếu bạn sẽ tìm thấy;)
Joe Taras

Câu trả lời:


252

Thử cái này:

Xóa các ràng buộc DF_Movies_Rating__48CFD27E trước khi thay đổi loại trường của bạn.

Ràng buộc thường được tạo tự động bởi DBMS (SQL Server).

Để xem các ràng buộc được liên kết với bảng, hãy mở rộng các thuộc tính bảng trong Object explorer , theo sau là các ràng buộc thể loại như dưới đây:

Cây của bàn của bạn

Bạn phải loại bỏ các ràng buộc trước khi thay đổi loại trường.


40
@ManirajSS: THAY ĐỔI BẢNG DROP CONSTRAINT của bạn DF_Movies_Rating__48CFD27E
Joe Taras

18
Điều gì đã kích hoạt việc tạo ra các ràng buộc? Tôi có một loạt chúng, và tôi thực sự không muốn chúng!
Simon Parker

5
Hmm, và phải làm gì nếu tôi muốn sử dụng chuyển đổi DB của khung công tác của tôi (Laravel) và dropColumn ở đó? Tôi không biết làm cách nào để loại bỏ ràng buộc có tên bí ẩn, được tự động tạo bởi máy chủ SQL :(
JustAMartin

2
Tôi chắc chắn: Tôi đã đánh rơi nó và các ràng buộc thư mục trở nên trống rỗng và khi tôi chạy ứng dụng hoặc gọi update-databaselại nó, tôi đã đăng lại vấn đề này: stackoverflow.com/questions/40267769/iêu
mshwf

2
Tại sao SQLServer không bỏ qua sự chống đối ngầm? Rốt cuộc, nó đã tạo ra nó một cách ngấm ngầm!
youcantryreachingme

46

Đây là tsqlcách

 ALTER TABLE yourtable DROP CONSTRAINT constraint_name     -- DF_Movies_Rating__48CFD27E

Để đầy đủ, điều này chỉ hiển thị nhận xét của @Joe Taras như một câu trả lời


46

Tôi đang thêm điều này như một phản hồi để giải thích ràng buộc đến từ đâu. Tôi đã cố gắng thực hiện nó trong các bình luận nhưng thật khó để chỉnh sửa độc đáo ở đó: - /

Nếu bạn tạo (hoặc thay đổi) một bảng có cột có giá trị mặc định, nó sẽ tạo ra ràng buộc cho bạn.

Trong bảng của bạn chẳng hạn, nó có thể là:

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

Nó sẽ tạo ra các ràng buộc cho 100 mặc định.

Nếu bạn thay vì tạo nó như vậy

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

Sau đó, bạn nhận được một ràng buộc được đặt tên độc đáo, dễ tham chiếu hơn khi bạn thay đổi bảng đã nói.

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;

Bạn có thể kết hợp 2 câu lệnh cuối để bạn thay đổi cột và đặt tên cho ràng buộc trong một dòng (bạn phải biết nếu đó là một bảng hiện có)


Cảm ơn bạn đã thêm thông tin về cách tránh sự cố bằng cách đặt tên cho tất cả các ràng buộc ở vị trí đầu tiên. (Đó là, tránh vấn đề bỏ các ràng buộc được đặt tên ngẫu nhiên)
youcantryreachingme

22

Vì ràng buộc có tên không thể đoán trước, bạn có thể viết tập lệnh đặc biệt ( DropConstraint ) để xóa nó mà không biết tên của nó (đã được thử nghiệm tại 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));    
}

Câu trả lời này hoạt động rất tốt trong môi trường dựa trên Di chuyển nơi bạn không đủ khả năng để ràng buộc tên mã hóa cứng.
Menion Leah

Nếu bạn tạo hàm bao bọc / mở rộng / nạp chồng cho AlterColumn - như AlterColumnX - bạn có thể bao gồm logic DropConstraint trong đó - và bạn có thể chuyển vào tên bảng & tên cột để bạn không phải viết lại chúng.
N73k

10

MS SQL Studio chăm sóc khi bạn xóa cột nhưng nếu bạn cần Xóa ràng buộc theo chương trình thì đây là giải pháp đơn giản

Đây là một đoạn mã sẽ thả một cột với ràng buộc mặc định:

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

Chỉ cần thay thế TableNameColumnName bằng các giá trị thích hợp. Bạn có thể chạy nó một cách an toàn ngay cả khi cột đã bị hủy.

Phần thưởng : Đây là mã để loại bỏ khóa ngoại và các loại ràng buộc khác.

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


1
đã cứu mạng tôi hai lần bây giờ. Cả hai, phải xóa các ràng buộc kiểm tra. Trước hết tôi phải sử dụng truy vấn đầu tiên. Thứ hai, tôi phải sử dụng truy vấn thứ hai vì không tìm thấy ràng buộc kiểm tra trong bảng SYS.DEFAULT_CONSTRAINTS. Cảm ơn rất nhiều!
Chủ nhật ngày

8

Khi chúng tôi cố gắng thả một cột phụ thuộc vào thì chúng tôi thấy loại lỗi này:

Đối tượng 'DF __ *' phụ thuộc vào cột ''.

loại bỏ các ràng buộc phụ thuộc vào cột đó với:

ALTER TABLE TableName DROP CONSTRAINT dependent_constraint;

Thí dụ:

Msg 5074, Cấp 16, Bang 1, Dòng 1

Đối tượng ' DF__Emp viên__Colf__1273C1CD' phụ thuộc vào cột 'Colf'.

Msg 4922, Cấp 16, Bang 9, Dòng 1

ALTER TABLE DROP COLUMN Colf không thành công vì một hoặc nhiều đối tượng truy cập vào cột này.

Hạn chế thả (DF__Emprocod__Colf__1273C1CD):

ALTER TABLE Employees DROP CONSTRAINT DF__Employees__Colf__1273C1CD;

Sau đó, bạn có thể thả cột:

Alter Table TableName Drop column ColumnName

1

Giải pháp :

mở bảng cơ sở dữ liệu -> mở rộng bảng -> mở rộng các ràng buộc và xem điều này

ảnh chụp màn hình


Mặc dù mã này có thể trả lời câu hỏi, cung cấp ngữ cảnh bổ sung về lý do và / hoặc cách mã này trả lời câu hỏi cải thiện giá trị lâu dài của nó.
Vịt Donald

-1

Tôi gặp lỗi này khi cố gắng chạy di chuyển để khắc phục sự cố. Tôi đã đổi tên cột và tạo lại di chuyển bằng cách sử dụng

add-migration migrationname -force

trong bảng điều khiển quản lý gói. Sau đó tôi đã có thể chạy

update-database

thành công


2
Hãy cẩn thận, điều này không đổi tên một cột - nó thả cột và thêm một cột mới. Bạn sẽ mất mọi dữ liệu đã từng tồn tại trong cột trừ khi bạn thêm mã tùy chỉnh trong quá trình di chuyển.
caesay
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.