El objeto 'DF __ *' depende de la columna '*' - Cambiar int a double

168

Básicamente obtuve una tabla en mi base de datos EF con las siguientes propiedades:

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

Funciona bien, sin embargo, cuando cambio el int de Rating para que sea doble, aparece el siguiente error al actualizar la base de datos:

El objeto 'DF_ Movies _Rating__48CFD27E' depende de la columna 'Calificación'. ALTER TABLE ALTER COLUMN La calificación falló porque uno o más objetos acceden a esta columna.

¿Cual es el problema?

Jordan Axe
fuente
1
Elimine la restricción DF_Movies_Rating__48CFD27E y luego cambie el tipo de su campo
Joe Taras
@JoeTaras Pero nunca he creado una restricción llamada así. ¿Qué es y dónde lo encuentro?
Jordan Axe
2
Cuando cree un campo DBMS cree automáticamente una restricción. Si expande la información de su tabla, en la sección de restricciones la encontrará. Dime si encontrarás;)
Joe Taras

Respuestas:

252

Prueba esto:

Elimine la restricción DF_Movies_Rating__48CFD27E antes de cambiar su tipo de campo.

La restricción generalmente es creada automáticamente por el DBMS (SQL Server).

Para ver la restricción asociada con la tabla, expanda los atributos de la tabla en el Explorador de objetos , seguido de la categoría Restricciones como se muestra a continuación:

Árbol de tu mesa

Debe eliminar la restricción antes de cambiar el tipo de campo.

Joe Taras
fuente
40
@ManirajSS: ALTER TABLE yourtable DROP CONSTRAINT DF_Movies_Rating__48CFD27E
Joe Taras el
18
¿Qué desencadenó la creación de la restricción? Tengo un montón de ellos, ¡y realmente no los quiero!
Simon Parker
55
Hmm, ¿y qué hacer si quiero usar migraciones DB de mi marco (Laravel) y dropColumn allí? No tengo idea de cómo eliminar la restricción que tiene un nombre misterioso,
generado automáticamente
2
Estoy seguro: lo dejé caer y la carpeta Restricciones se vacía, y cuando ejecuto la aplicación o la llamo update-databasea recrearse nuevamente
publiqué
2
¿Por qué diablos SQLServer no deja caer la restricción implícitamente? ¡Después de todo, lo creó implícitamente!
youcantryreachingme
46

Este es el tsqlcamino

 ALTER TABLE yourtable DROP CONSTRAINT constraint_name     -- DF_Movies_Rating__48CFD27E

Para completar, esto solo muestra el comentario de @Joe Taras como respuesta

Luis Siquot
fuente
46

Estoy agregando esto como respuesta para explicar de dónde viene la restricción. Traté de hacerlo en los comentarios, pero es difícil de editar bien allí: - /

Si crea (o modifica) una tabla con una columna que tiene valores predeterminados, creará la restricción para usted.

En su tabla, por ejemplo, podría ser:

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

Creará la restricción para el valor predeterminado 100.

Si en cambio lo creas así

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

Luego obtienes una restricción bien nombrada que es más fácil de referencia cuando estás alterando dicha tabla.

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;

Puede combinar esas 2 últimas declaraciones para modificar la columna y nombrar la restricción en una línea (de todos modos, debe hacerlo si es una tabla existente)

h3adache
fuente
Gracias por agregar información sobre cómo evitar el problema al nombrar todas las restricciones en primer lugar. (Es decir, evite el problema de
eliminar
22

Como la restricción tiene un nombre impredecible, puede escribir un script especial ( DropConstraint ) para eliminarlo sin saber su nombre (se probó en 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));    
}
Slava Utesinov
fuente
Esta respuesta funciona muy bien en un entorno basado en la migración donde no puede permitirse codificar el nombre de restricción.
Menion Leah
Si realiza una función de envoltura / extensión / sobrecargada para AlterColumn, como AlterColumnX, puede incluir esa lógica DropConstraint allí, y puede pasar el nombre de la tabla y el nombre de la columna para que no tenga que volver a escribirlos.
N73k
10

MS SQL Studio se encarga de eliminar la columna, pero si necesita eliminar la restricción mediante programación, aquí hay una solución simple

Aquí hay un fragmento de código que soltará una columna con una restricción predeterminada:

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

Simplemente reemplace TableName y ColumnName con los valores apropiados. Puede ejecutar esto de manera segura incluso si la columna ya se ha descartado.

Bonificación : Aquí está el código para soltar claves foráneas y otros tipos de restricciones.

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

ARIZONA_
fuente
1
Me salvó la vida dos veces ahora. Ambos, teniendo que eliminar las restricciones de verificación. En primer lugar tengo que usar la primera consulta. En segundo lugar, tengo que usar la segunda consulta porque la restricción de verificación no se encontró en la tabla SYS.DEFAULT_CONSTRAINTS. ¡Muchas gracias!
Domingo
8

Cuando intentamos soltar una columna de la que depende, vemos este tipo de error:

El objeto 'DF __ *' depende de la columna ''.

elimine la restricción que depende de esa columna con:

ALTER TABLE TableName DROP CONSTRAINT dependent_constraint;

Ejemplo:

Msg 5074, Nivel 16, Estado 1, Línea 1

El objeto ' DF__Empleados__Colf__1273C1CD' depende de la columna 'Colf'.

Msg 4922, Nivel 16, Estado 9, Línea 1

ALTER TABLE DROP COLUMN Colf falló porque uno o más objetos acceden a esta columna.

Restricción de caída (DF__Empleados__Colf__1273C1CD):

ALTER TABLE Employees DROP CONSTRAINT DF__Employees__Colf__1273C1CD;

Entonces puedes soltar la columna:

Alter Table TableName Drop column ColumnName
Jinna Balu
fuente
1

Solución:

abrir tabla de base de datos -> expandir tabla -> expandir restricciones y ver esto

captura de pantalla

Arup Mahapatra
fuente
Si bien este código puede responder a la pregunta, proporcionar un contexto adicional con respecto a por qué y / o cómo responde a la pregunta mejora su valor a largo plazo.
Pato Donald
-1

Tuve este error al intentar ejecutar una migración para solucionarlo. Cambié el nombre de la columna y volví a generar la migración usando

add-migration migrationname -force

en la consola del administrador de paquetes. Entonces pude correr

update-database

exitosamente.

Avaricia Kirsten
fuente
2
Tenga cuidado, esto no cambia el nombre de una columna: deja caer la columna y agrega una nueva columna. Perderá los datos que solían existir en la columna a menos que agregue código personalizado en la migración.
caesay