c# - first - Entidad Framework La sentencia ALTER TABLE está en conflicto con la restricción FOREIGN KEY
net core entity framework existing database (9)
Compruebe que no haya datos existentes en la base de datos que entren en conflicto con la restricción FK que causa la creación fallar.
Al actualizar la base de datos en Entity Framework, primer código de migración, aparece este error:
La instrucción ALTER TABLE entró en conflicto con la restricción FOREIGN KEY "FK_dbo.Clients_dbo.MedicalGroups_MedicalGroupId". El conflicto ocurrió en la base de datos "hrbc", tabla "dbo.MedicalGroups", columna "Id".
Esta es mi clase:
public partial class Client
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int? MedicalGroupId { get; set; }
[ForeignKey("MedicalGroupId")]
public virtual MedicalGroups MedicalGroup { get { return _MedicalGroup; } set { _MedicalGroup = value; } }
}
Aquí está mi 2da clase:
public partial class MedicalGroups
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
}
Y esta es mi migración que estoy tratando de aplicar:
public override void Up()
{
AddForeignKey("dbo.Clients", "MedicalGroupId", "dbo.MedicalGroups", "Id");
CreateIndex("dbo.Clients", "MedicalGroupId");
}
Creo que @Cory te estaba acercando a la solución correcta, simplemente no te tomaste el tiempo de investigar.
En el código de migración adicional, la migración probablemente se haya generado
public override void Up()
{
AddColumn("dbo.ClientContacts", "FamilialRelationshipId", c => c.Int(nullable: false));
CreateIndex("dbo.ClientContacts", "FamilialRelationshipId");
AddForeignKey("dbo.ClientContacts", "FamilialRelationshipId", "dbo.FamilialRelationships", "FamilialRelationshipId");
}
Aviso nullable: falso; Si su modelo tiene una identificación de int en lugar de int? (nullable int) el código de migración establecerá las anulaciones a falso. Su modelo muestra que está utilizando un int no anulable que por defecto es 0, y probablemente no tenga un ítem de clave foránea con un valor de 0.
Ahora, tendrá que crear un valor predeterminado, que existe en la tabla de clave externa, o Crear la restricción sin comprobación si está utilizando SQL Server para crear la restricción. Sin embargo, recuerde esto: si decora su propiedad con un atributo [DefaultValue (0)], no cambiará los datos existentes, como lo haría un SQL Column Add, si se especificó un valor predeterminado.
Te recomiendo que cambies tu clase de modelo para permitir una int en nulo. Luego, en su método seed, cree un método simple contra dbcontext para actualizar la nueva columna con un valor predeterminado, porque el atributo [DefaultValue] en las anotaciones de datos no modificará sus datos.
Add-Migration / Update-Database para crear la columna y la restricción. A continuación, modifique su modelo si desea permitir una int no anulable, y suponiendo que haya cambiado todas las filas a algún valor válido para la clave externa, Add-Migration / Update-database nuevamente. Esto le proporciona una cadena ininterrumpida en la migración de su modelo. Te será útil más adelante cuando publiques en un sitio en vivo, porque el flujo de tus cambios en el modelo de datos estará intacto.
- Espero que esto ayude.
Ejecute el comando Add-Migration InitialCreate -IgnoreChanges en la consola del Administrador de paquetes. Esto crea una migración vacía con el modelo actual como una instantánea.
Ejecute el comando Actualizar-Base de datos en la consola del Administrador de paquetes. Esto aplicará la migración InitialCreate a la base de datos. Dado que la migración real no contiene ningún cambio, simplemente agregará una fila a la tabla __MigrationsHistory indicando que esta migración ya se ha aplicado.
Puede obtener más detalles aquí: https://msdn.microsoft.com/en-us/library/dn579398(v=vs.113).aspx
Este error le dice que está violando la restricción de clave externa. Para resolverlo, tiene algunas soluciones
- Corrija sus datos : en algún lugar hay registros en la tabla
Clients
que tienen un MedicalGroupId que no existe en la tablaMedicalGroups
. Escriba una consulta para averiguar qué ID no existen en la tablaMedicalGroups
y arregle los datos usted mismo. - Elimine la restricción de clave externa : obviamente, si elimina la restricción de clave externa ya no le molestará este mensaje. Desafortunadamente, la base de datos ya no hará cumplir esta relación y podría empeorar este problema en el futuro.
- Crear restricción usando
WITH NOCHECK
- Puede crear su restricción de clave externa usando la opciónWITH NOCHECK
. Esta opción le dice a SQL Server que no aplique esta restricción a los datos existentes. SQL Server VERIFICARÁ esta restricción en INSERTS / UPDATES / DELETES futuros.
Para otros que pueden aterrizar aquí, podría haber una solución realmente simple si está utilizando Code-First Entity Framework y simplemente está tratando de agregar una nueva columna requerida a una tabla con datos existentes.
Nota: Antes de hacer esto, solo debe saber que deberá agregar un valor válido a esta nueva columna para todas las filas existentes. Piense qué valor va a agregar a las filas existentes antes de continuar. Es posible que desee proporcionar un valor que indique "Inválido" o "Desconocido" en la tabla de búsqueda requerida.
En su modelo, configure la columna como anulable agregando el? después de la int. Guarde y compile el modelo. Ejecute Update-Database.
Ejemplo:
[ForeignKey("Title")]
public int? TitleId { get; set; }
En el archivo db, actualice la tabla reemplazando los valores NULL con un valor de búsqueda válido. En mi caso, agregué "Desconocido" a mi tabla de búsqueda de título y luego edité en bloque todas las filas para hacer referencia a ese ID de búsqueda.
De vuelta en su modelo, elimine el ''?'' por lo que la columna ya no puede contener nulos. Guarde y compile el modelo y luego ejecute Update-Database
Ahora deberías estar listo para ir.
Suponiendo que sus migraciones están en el orden correcto, es decir, la tabla asociada con la clave externa se creará antes de la referencia. Sigue los siguientes pasos:
- Copia de seguridad de la base de datos actual de SQL Management Studio (si es necesario)
- Eliminar la base de datos del estudio de administración de SQL
- Escriba ''Actualizar-Base de datos'' en Visual Studio ''Package Manager Console''
También tuve este problema con el conjunto defaultValue, di:
"El objeto depende de la columna ALTER TABLE ALTER COLUMN failed porque uno o más objetos acceden a esta columna".
Finalizado muevo el AddForeignKey / DropForeignKey a una nueva migración y los ejecuté en comandos separados de la base de datos de actualización (no excedo ambas migraciones en un comando y luego falló).
public override void Up()
{
CreateTable(
"dbo.DecisionAccesses",
c => new
{
Id = c.Int(nullable: false),
Name = c.String(nullable: false, maxLength: 50),
})
.PrimaryKey(t => t.Id);
CreateTable(
"dbo.DecisionPersonStatus",
c => new
{
Id = c.Int(nullable: false),
Name = c.String(nullable: false, maxLength: 50),
})
.PrimaryKey(t => t.Id);
AddColumn("dbo.DecisionForm_DecisionFields", "DecisionAccessId", c => c.Int(nullable: false, defaultValue: (int)DecisionAccess.Creator));
AddColumn("dbo.DecisionMatterPersons", "DecisionPersonStatusId", c => c.Int(nullable: false, defaultValue: (int)DecisionAccess.Creator));
CreateIndex("dbo.DecisionForm_DecisionFields", "DecisionAccessId");
CreateIndex("dbo.DecisionMatterPersons", "DecisionPersonStatusId");
//I moved outcommented to next migration and ran the migrations in separate steps to avoid: (The object is dependent on column ALTER TABLE ALTER COLUMN failed because one or more objects access this column)
//AddForeignKey("dbo.DecisionForm_DecisionFields", "DecisionAccessId", "dbo.DecisionAccesses", "Id", cascadeDelete: true);
//AddForeignKey("dbo.DecisionMatterPersons", "DecisionPersonStatusId", "dbo.DecisionPersonStatus", "Id", cascadeDelete: true);
}
public override void Down()
{
//Moved to next migration
//DropForeignKey("dbo.DecisionMatterPersons", "DecisionPersonStatusId", "dbo.DecisionPersonStatus");
//DropForeignKey("dbo.DecisionForm_DecisionFields", "DecisionAccessId", "dbo.DecisionAccesses");
}
Tengo la solución de mi problema. El problema es "datos" que tengo en la tabla de mis clientes. Debido a que mi tabla de clientes tiene valores de medicalgroupid que en realidad no existen, es por eso que me da error en la restricción de clave externa.
Update Client set MedicalGroupId = NULL
este problema aparece porque su tabla no está vacía. entonces debes agregar el nuevo campo sin asociarlo como clave externa. public int? MedicalGroupId {get; conjunto; } . Y ejecute el comando update-database en la consola de administración de paquetes. Luego llene el campo en esta tabla (cliente) con los datos correctos (el valor existe en MedicalGroupsId). Inserte la línea para crear la clave externa [ForeignKey ("MedicalGroupId")] public group MedicalGroups MedicalGroup {get {return _MedicalGroup; } set {_MedicalGroup = value; }} . al final ejecuta el comando update-database. Estará bien.