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.

MySQL / EF 6.0 Core La relación uno a uno devuelve nulo.

Estoy utilizando EF Core 6.0 con MySQL (Pomelo.EntityFrameworkCore.MySql v6.0).
Estoy configurando mi base de datos a través de code first. Aquí están mis 2 modelos (simplificados):

public class Store : BaseEntity
{
     public string Name { get; set; }
     public virtual User? Owner { get; set; }
     public int? OwnerId { get; set; }
}

public class User : BaseEntity
{
     public string? Name { get; set; }
     public virtual Store? Store { get; set; }
}

Para ambos, tengo lo siguiente:

[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }

como clave primaria (heredado de BaseEntity).

También tengo la carga diferida (Lazy Loading) habilitada aquí:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder.UseLazyLoadingProxies();
}

y en el Program.cs:

builder.Services.AddDbContext<appdbcontext>(opt => opt
    .UseLazyLoadingProxies()
    .ConfigureWarnings(warning => warning.Ignore(CoreEventId.DetachedLazyLoadingWarning))
    .EnableSensitiveDataLogging()
    .UseMySql(
        Globals.DB_CONNECTION_STRING, new MySqlServerVersion(Globals.MYSQL_SERVER_VERSION),
        o => o.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery)
    ));

Ahora, respecto al problema: estoy intentando obtener una tienda de la base de datos utilizando el siguiente código:

Store? store = await dbContext.Stores
    .Include(x => x.Owner)
    .FirstOrDefaultAsync(x => x.Owner.Id == ownerId && x.Id == storeId);

Obtengo los detalles de la tienda, pero el objeto Owner y OwnerId son nulos. Puedo ver los datos en la base de datos (por ejemplo, veo que OwnerId está configurado para esta tienda específica), pero en el código son nulos.

Leí en SO que Pomelo tiene algunos problemas al configurar las propiedades de navegación, así que lo configuré manualmente en OnModelCreating de la siguiente manera:

modelBuilder.Entity<user>()
    .HasOne(x => x.Store)
    .WithOne(x => x.Owner);

Pero eso no funcionó.

La misma configuración funciona perfectamente con MSSQL.

¿Alguna idea?

Gracias.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    El problema aquí es que Entity Framework Core 6.0 con MySQL (Pomelo.EntityFrameworkCore.MySql v6.0) tiene algunos problemas al configurar las propiedades de navegación. Aunque has intentado configurarlo manualmente en OnModelCreating, parece que no se ha resuelto el problema.

    Una posible solución es intentar desactivar la carga diferida y ver si eso ayuda. Puedes hacer esto eliminando la llamada UseLazyLoadingProxies() en el método OnConfiguring y eliminando la palabra clave virtual de la propiedad Owner en el modelo Store.

    Otra posible solución es intentar usar la carga anticipada en lugar de la carga diferida. Puedes hacer esto reemplazando el método Include() con el método de extensión Include() del espacio de nombres Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions. Por ejemplo:

    Store? store = await dbContext.Stores
        .Include(x => x.Owner)
            .ThenInclude(x => x.Store)
        .FirstOrDefaultAsync(x => x.Owner.Id == ownerId && x.Id == storeId);
    

    Esto cargará de manera anticipada el objeto Owner junto con su objeto Store.

    Si ninguna de estas soluciones funciona, es posible que debas considerar el uso de un proveedor de base de datos o un ORM diferente que se adapte mejor a tus necesidades.

Comments are closed.