Te recomendamos que pruebes esta respuesta en un entorno controlado antes de pasarlo a producción, un saludo.
Solución:
Debe decirle a Entity Framework qué propiedades en ambas entidades están involucradas en una asociación. En la API de mapeo fluida, esto es:
protected override void OnModelCreating(ModelBuilder modelBuilder)
modelBuilder.Entity().HasMany(t => t.HomeGames)
.WithOne(g => g.HomeTeam)
.HasForeignKey(g => g.HomeTeamId);
modelBuilder.Entity().HasMany(t => t.AwayGames)
.WithOne(g => g.AwayTeam)
.HasForeignKey(g => g.AwayTeamId).OnDelete(DeleteBehavior.Restrict);
Debe utilizar la API fluida porque, de forma predeterminada, EF intentará crear dos keys con eliminación en cascada. SQL Server no lo permitirá debido a su infame restricción de “múltiples rutas en cascada”. Uno de los keys no debería estar en cascada, que solo se puede configurar mediante la API fluida.
Basado en relaciones – EF Core | Microsoft Docs puede usar anotaciones de datos
Anotaciones de datos
Hay dos anotaciones de datos que se pueden utilizar para configurar relaciones, [ForeignKey] y [InverseProperty].
[ForeignKey]
Puede utilizar las anotaciones de datos para configurar qué propiedad se debe utilizar como key propiedad para una relación determinada. Esto se hace normalmente cuando el extranjero key la propiedad no se descubre por convención.
[InverseProperty]
Puede utilizar las anotaciones de datos para configurar cómo se emparejan las propiedades de navegación en las entidades dependientes y principales. Normalmente, esto se hace cuando hay más de un par de propiedades de navegación entre dos tipos de entidad.
public class Team
public int Id get; set;
public string Name get; set;
[InverseProperty("HomeTeam")]
public ICollection HomeGames get; set;
[InverseProperty("AwayTeam")]
public ICollection AwayGames get; set;
public class Game
public int Id get; set;
public DateTime Date get; set;
public int HomeTeamId get; set;
[ForeignKey("HomeTeamId")]
public Team HomeTeam get; set;
public int AwayTeamId get; set;
[ForeignKey("AwayTeamId")]
public virtual Team AwayTeam get; set;
si usa db.Database.Migrate () obtendrá un error
System.Data.SqlClient.SqlException: ‘La introducción de la restricción FOREIGN KEY’ FK_Games_Teams_HomeTeamId ‘en la tabla’ Games ‘puede causar ciclos o múltiples rutas en cascada. Especifique EN ELIMINAR SIN ACCIÓN o EN ACTUALIZAR SIN ACCIÓN, o modifique otras restricciones de CLAVE EXTRANJERA. No se pudo crear restricción o índice. Ver errores anteriores
puede hacer HomeTeamId AwayTeamId ¿En t? anulable
public class Team
public int Id get; set;
public string Name get; set;
[InverseProperty("HomeTeam")]
public ICollection HomeGames get; set;
[InverseProperty("AwayTeam")]
public ICollection AwayGames get; set;
public class Game
public int Id get; set;
public DateTime Date get; set;
public int? HomeTeamId get; set;
[ForeignKey("HomeTeamId")]
public Team HomeTeam get; set;
public int? AwayTeamId get; set;
[ForeignKey("AwayTeamId")]
public virtual Team AwayTeam get; set;
o consulte Eliminar en cascada – EF Core | Documentos de Microsoft
-
aquí el código completo que probé y funcionando ( db primero no codifica primero )
-
para el primer uso del código ¿En t?
-
para Program.cs
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; using Microsoft.EntityFrameworkCore; namespace stackoverflow54196199 public class Team public int Id get; set; public string Name get; set; [InverseProperty("HomeTeam")] public ICollection
HomeGames get; set; [InverseProperty("AwayTeam")] public ICollection AwayGames get; set; public class Game public int Id get; set; public DateTime Date get; set; public int HomeTeamId get; set; [ForeignKey("HomeTeamId")] public Team HomeTeam get; set; public int AwayTeamId get; set; [ForeignKey("AwayTeamId")] public Team AwayTeam get; set; public class MyContext : DbContext public DbSet Games get; set; public DbSet Teams get; set; protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) optionsBuilder.UseSqlServer("Server=.;Integrated Security=true;Initial Catalog=stackoverflow54196199;Persist Security Info=False;"); class Program static void Main(string[] args) var db = new MyContext(); foreach (var game in db.Games.Include(i => i.AwayTeam).Include(i => i.HomeTeam)) Console.WriteLine(game.HomeTeam.Name); Console.WriteLine(game.AwayTeam.Name); Console.ReadLine(); -
para stackoverflow54196199.csproj
Exe netcoreapp2.1
Comentarios y puntuaciones
Si entiendes que ha sido útil nuestro post, agradeceríamos que lo compartas con otros entusiastas de la programación de esta forma nos ayudas a dar difusión a nuestro contenido.