Saltar al contenido

Entity Framework Core: múltiples relaciones de uno a varios entre dos entidades

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.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *