Об'єкт 'DF __ *' залежить від стовпця '*' - Зміна int на подвійний


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

Це добре працює, але коли я змінюю int Rating на подвійний, я отримую таку помилку під час оновлення бази даних:

Об'єкт "DF_ Movies _Rating__48CFD27E" залежить від стовпця "Рейтинг". ALTER TABLE ALTER COLUMN Рейтинг не вдався, оскільки один або більше об'єктів отримують доступ до цього стовпця.

У чому проблема?


1
Видаліть обмеження DF_Movies_Rating__48CFD27E, а потім змініть тип свого поля
Джо Тарас

@JoeTaras Але я ніколи не створював такого обмеження. Що це таке і де його знайти?
Jordan Axe

2
Під час створення поля СУБД створює автоматично обмеження. Якщо ви розгорнете інформацію про свою таблицю, у розділі обмежень ви знайдете її. Скажіть, чи знайдете;)
Джо Тарас

Відповіді:


252

Спробуйте це:

Видаліть обмеження DF_Movies_Rating__48CFD27E перед тим, як змінити тип поля.

Обмеження зазвичай створюється автоматично СУБД (SQL Server).

Щоб побачити обмеження, пов’язані з таблицею, розгорніть атрибути таблиці в Об’єктові провідника , а потім категорію Обмеження, як показано нижче:

Дерево вашого столу

Ви повинні усунути обмеження перед тим, як змінити тип поля.


40
@ManirajSS: ВІДПРАВЛІТЬ ТАБЛИЦЮ вашої розсильної конфігурації DF_Movies_Rating__48CFD27E
Джо Тарас

18
Що спровокувало створення обмеження? У мене їх купа, і я їх дуже не хочу!
Саймон Паркер

5
Хм, а що робити, якщо я хочу використовувати міграцію БД моєї фреймворку (Laravel) та dropColumn? Я не маю уявлення, як скинути обмеження, яке має таємниче ім'я, автогенероване сервером SQL :(
JustAMartin

2
Я впевнений: я це і падаю на порядок обмеження папки стають порожніми, і коли я запустити додаток або викликати update-databaseйого відтворити себе знову я відправив це питання: stackoverflow.com/questions/40267769 / ...
mshwf

2
Чому чорт не 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;

Ви можете комбінувати ці два останні твердження, щоб ви змінили стовпець і назвали обмеження в одному рядку (ви повинні, якщо це все-таки наявна таблиця)


Дякуємо, що додали інформацію про те, як уникнути проблеми, назвавши в першу чергу всі обмеження. (Тобто уникайте проблеми скасування випадково названих обмежень)
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));    
}

Ця відповідь чудово працює в середовищі на основі міграції, де ви не можете дозволити собі жорсткий код імені обмеження.
Меніон Лія

Якщо ви зробите функцію обгортки / розширення / перевантаження для 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;

Приклад:

Msg 5074, рівень 16, стан 1, рядок 1

Об'єкт ' DF__E Employees__Colf__1273C1CD' залежить від стовпця 'Colf'.

Msg 4922, рівень 16, стан 9, рядок 1

ALTER TABLE DROP COLUMN Colf не вдалося, оскільки один або більше об'єктів отримують доступ до цього стовпця.

Обмеження для падіння (DF__E 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
Будьте уважні, цей стовпець не перейменовується - він скидає стовпчик і додає новий стовпець. Ви втратите будь-які дані, які раніше існували у стовпці, якщо ви не додасте спеціальний код під час міграції.
ceesay
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.