Entity framework 7 en ASP.NET MVC6 clave externa múltiple para la misma tabla

asp.net-mvc entity-framework entity-framework-core

Pregunta

Hola, tengo el mismo problema que un post anterior que está aquí, la oferta de solución que no funciona para mí en MVC 6 con EF7 es simple

public class Match
{
    [Key]
    public int MatchId { get; set; }

    public DateTime playday { get; set; }
    public float HomePoints { get; set; }
    public float GuestPoints { get; set; }

    public int HomeTeamId { get; set; }
    public int GuestTeamId { get; set; }

    [ForeignKey("HomeTeamId")]
    [InverseProperty("HomeMatches")]
    public virtual Team HomeTeam { get; set; }

    [ForeignKey("GuestTeamId")]
    [InverseProperty("AwayMatches")]
    public virtual Team GuestTeam { get; set; }

}

public class Team
{
    public int TeamId { get; set; }
    public String name { get; set; }

    public virtual ICollection<Match> HomeMatches { get; set; }
    public virtual ICollection<Match> AwayMatches { get; set; }
}

Esta es la mejor manera que encontré, porque puedo agregar una nueva migración y todo está bien, pero cuando actualizo la base de datos obtengo un error como este.

La introducción de la restricción FOREIGN KEY 'FK_Match_Team_HomeTeamId' en la tabla 'Coincidencia' puede provocar ciclos o múltiples rutas en cascada. Especifique ON DELETE NO ACTION o ON UPDATE NO ACTION, o modifique otras restricciones FOREIGN KEY. No se pudo crear restricción o índice. Ver errores anteriores.

Respuesta aceptada

Analicé el problema en detalle durante la preparación de la respuesta y puedo sugerirle dos soluciones al problema.

El problema existe debido a dos propiedades en la clase Match

public int HomeTeamId { get; set; }
public int GuestTeamId { get; set; }

y las claves externas HomeTeamId y GuestTeamId que será generada. EF7 genera las claves foráneas con ON DELETE CASCADE , que no se puede usar para más como una clave foránea. La implementación actual de Entity Framework (RC1) no tiene ningún atributo de anotación, que puede utilizar para cambiar el comportamiento.

La primera solución del problema sería utilizar propiedades anulables como

public int HomeTeamId { get; set; }
public int GuestTeamId { get; set; }

o

public int HomeTeamId { get; set; }
public int GuestTeamId { get; set; }

Máximo una propiedad debe ser no anulable. Como resultado, el problema se resolverá, pero uno tendrá una pequeña desventaja, lo que podría no ser importante para algunos escenarios. El campo en la tabla de la base de datos para la propiedad anulable no tendrá propiedad NOT NULL en la definición de la columna.

Si es necesario para mantener tanto HomeTeamId y GuestTeamId no anulable entonces se puede resolver el problema mediante la modificación de la clase de contexto (heredado de DbContext), donde las clases Match y Team usarse.

Ya tienes alguna clase de contexto definida a continuación.

public int HomeTeamId { get; set; }
public int GuestTeamId { get; set; }

Para resolver el problema descrito, puede agregar OnModelCreating protegido en la clase que establece explícitamente

public int HomeTeamId { get; set; }
public int GuestTeamId { get; set; }

Puede usar la causa DeleteBehavior.Restrict en ambas claves externas (en lugar de DeleteBehavior.Cascade en una). Es importante remarcar que el último enfoque permite mantener tanto HomeTeamId y GuestTeamId , al igual que los campos correspondientes en la base de datos, como no anulable.

Vea la documentación para información adicional.


Respuesta popular

Si lo prefiere, puede crear en la base de datos manualmente este FK con eliminación en cascada y comprobar por qué está utilizando este bucle circular en cascada. Para entender que necesitamos las otras tablas o la estructura de la base de datos involucrada. Inspeccione su base de datos (con un diagrama, por ejemplo), dibuje sus tablas conectadas, sus FK y para cada estudio la operación que planeó (eliminación en cascada, ninguna acción, ...) y la dirección de ellos. Rellena un bucle cuando intentas insertar ese FK por error.

La siguiente fase es entender si lo desea o no, ¿es un diseño de base de datos no deseado? ¿O simplemente no necesitas esta acción FK? En este caso, puede suprimirlo en varios niveles: en el modelo, en la configuración, ... consulte la otra publicación o la guía de EF para eso.




Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué