es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Configurar el comportamiento de eliminación con 2 relaciones utilizando Fluent API.

Estoy utilizando Fluent API en mi aplicación .NET Core con EF. Tengo un modelo de Chat entre 2 usuarios:

public class Chat
{<br>
    //(id, texto...)

    public string InitiatorId { get; set; }
    public ApplicationUser Initiator { get; set; }


    public string InvitedId { get; set; }
    public ApplicationUser Invited { get; set; }            
}
public class ApplicationUser 
{<br>
    //(id...)

    public List<chat> Chats{ get; set; }

}

El problema es que quiero que el chat se elimine si uno de estos usuarios se elimina y no puedo declararlo de esa manera en mi dbContext:

builder.Entity<chat>()
            .HasOne(x => x.Initiator)
            .WithMany(x => x.Chats)
            .OnDelete(DeleteBehavior.Cascade);
builder.Entity<chat>()
            .HasOne(x => x.Invited)
            .WithMany(x => x.Chats)
            .OnDelete(DeleteBehavior.Cascade);

Obtengo el siguiente error:

No se puede crear una relación entre ‘ApplicationUser.Chats’ y ‘Chat.Invited’ porque ya existe una relación entre ‘ApplicationUser.Chats’ y ‘Chat.Initiator’. Las propiedades de navegación solo pueden participar en una sola relación. Si desea anular una relación existente, llame a ‘Ignore’ en la navegación ‘Chat.Invited’ primero en ‘OnModelCreating’.

¿Existe una manera adecuada de hacer lo que quiero con Fluent API?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Sí, hay una manera adecuada de lograr lo que quieres utilizando Fluent API en tu aplicación .NET Core con EF. El mensaje de error que recibiste significa que ya existe una relación entre la propiedad de navegación ApplicationUser.Chats y la propiedad Chat.Initiator, y la propiedad Chat.Invited no puede participar en una segunda relación con ella. Para anular la relación existente y permitir que la propiedad Chat.Invited participe en una relación separada, puedes llamar al método Ignore en primer lugar en la propiedad Chat.Initiator dentro del método OnModelCreating de tu dbContext. Luego, puedes agregar el método OnDelete a ambas relaciones para eliminar el chat cuando uno de los usuarios sea eliminado. Tu código modificado se vería algo como esto:

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<chat>()
            .HasOne(x => x.Initiator)
            .WithMany(x => x.Chats)
            .OnDelete(DeleteBehavior.Cascade);
    
        modelBuilder.Entity<applicationuser>()
            .HasMany(x => x.Chats)
            .WithOne(x => x.Invited)
            .OnDelete(DeleteBehavior.Cascade);
    
        modelBuilder.Entity<applicationuser>()
            .HasMany(x => x.Chats)
            .WithOne(x => x.Initiator)
            .OnDelete(DeleteBehavior.Cascade);
    
        modelBuilder.Entity<chat>()
            .Ignore(x => x.Initiator);
    }
    

    Este código crea dos relaciones separadas entre la propiedad de navegación ApplicationUser.Chats y las propiedades Chat.Initiator y Chat.Invited, respectivamente, y configura ambas relaciones para eliminar el chat cuando uno de los usuarios sea eliminado. El método Ignore en la propiedad Chat.Initiator anula la relación existente y permite que la propiedad Chat.Invited participe en una relación separada.

    Con estos cambios, tu código debería funcionar como se espera.

Comments are closed.