c# - Relación de autorreferencia de muchos a muchos
entity-framework entity-framework-core (1)
La publicación que estás siguiendo es definitivamente incorrecta.
Cada colección o propiedad de navegación de referencia solo puede ser parte de una única relación. Mientras que la relación de muchos a muchos con la entidad de unión explícita se implementa con dos relaciones uno a muchos. La entidad de unión contiene dos propiedades de navegación de referencia, pero la entidad principal solo tiene una propiedad de navegación de colección única , que debe asociarse con una de ellas, pero no con ambas.
Una forma de resolver el problema es agregar una segunda propiedad de navegación de recopilación:
public class WordEntity
{
public long Id { get; set; }
public string Name { get; set; }
public string Json { get; set; }
public virtual List<WordSinonymEntity> Sinonyms { get; set; }
public virtual List<WordSinonymEntity> SinonymOf { get; set; } // <--
}
y especifique las asociaciones a través de una API fluida:
modelBuilder.Entity<WordSinonymEntity>()
.HasOne(pt => pt.Sinonym)
.WithMany(p => p.SinonymOf) // <--
.HasForeignKey(pt => pt.SinonymId)
.OnDelete(DeleteBehavior.Restrict); // see the note at the end
modelBuilder.Entity<WordSinonymEntity>()
.HasOne(pt => pt.Word)
.WithMany(t => t.Sinonyms)
.HasForeignKey(pt => pt.WordId);
Otra forma es dejar el modelo como está, pero mapear
WordSinonymEntity.Sinonym
a una asociación
unidireccional
(con propiedad de navegación de referencia y sin propiedad de navegación de colección correspondiente):
modelBuilder.Entity<WordSinonymEntity>()
.HasOne(pt => pt.Sinonym)
.WithMany() // <--
.HasForeignKey(pt => pt.SinonymId)
.OnDelete(DeleteBehavior.Restrict); // see the note at the end
modelBuilder.Entity<WordSinonymEntity>()
.HasOne(pt => pt.Word)
.WithMany(t => t.Sinonyms)
.HasForeignKey(pt => pt.WordId);
Solo asegúrese de que
WithMany
coincida exactamente con la presencia / ausencia de la propiedad de navegación correspondiente.
Tenga en cuenta que en ambos casos debe desactivar la cascada de eliminación para al menos una de las relaciones y eliminar manualmente las entidades de unión relacionadas antes de eliminar la entidad principal, porque las relaciones de autorreferencia siempre introducen posibles ciclos o problemas de ruta de cascada múltiple , evitando el uso de eliminación en cascada.
Soy nuevo en EF. Y me encontré con un problema con la creación de una relación de autorreferencia de muchos a muchos. Intenté usar la solución de: Entity Framework Core: relación de muchos a muchos con la misma entidad
mis entidades:
public class WordEntity
{
public long Id { get; set; }
public string Name { get; set; }
public string Json { get; set; }
public virtual List<WordSinonymEntity> Sinonyms { get; set; }
}
public class WordSinonymEntity
{
public long WordId { get; set; }
public virtual WordEntity Word { get; set; }
public long SinonymId { get; set; }
public virtual WordEntity Sinonym { get; set; }
}
y la siguiente configuración:
modelBuilder.Entity<WordSinonymEntity>()
.HasOne(pt => pt.Sinonym)
.WithMany(p => p.Sinonyms)
.HasForeignKey(pt => pt.SinonymId);
modelBuilder.Entity<WordSinonymEntity>()
.HasOne(pt => pt.Word)
.WithMany(t => t.Sinonyms)
.HasForeignKey(pt => pt.WordId);`
pero lleva a la próxima excepción.
System.InvalidOperationException: ''No se puede crear una relación entre'' WordEntity.Sinónimos ''y'' WordSinonymEntity.Word '', porque ya existe una relación entre'' WordEntity.Sinónimos ''y'' WordSinonymEntity.Sinonym ''. Las propiedades de navegación solo pueden participar en una sola relación ''.
¿Alguien me puede ayudar o puede sugerirme algunos ejemplos para aprender? Gracias.