. NET Core 3.1 - aplicación de consola + EF - .Incluir la fecha de carga

Normalmente encuentro una manera de hacer este trabajo pero aquí, los datos incluidos son nulos, funcionando en una aplicación de consola C#

(While) el mismo código funciona en mi aplicación web)

ambos Contacto y Company son nulo, EF no busca datos asociados

var context = new MyDBContext (configuration);
var leads = context.Leads.AsQueryable()
                            .Include(p => p.Company)  <<< does not create jointure
                            .Include(p => p.Contact)  <<< does not create jointure
                            .ToList();

Espero que las tablas asociadas sean pobladas en mi objeto

Traté de desactivar la carga perezosa pero aparentemente LozyLoadingEnabled no es parte de la clase de configuración

public class MyDBContext : DbContext
{
    IConfiguration configuration;

    public MyDBContext (IConfiguration configuration)
    {
        this.configuration = configuration;
        this.configuration.LazyLoadingEnabled = false;  <<< cannot compile
    }

Creo mi contexto db como lo hago en mi aplicación web

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        string connectionString = configuration.GetConnectionString("MyDBContext");
        optionsBuilder.UseSqlServer(connectionString,
                                    sqlServerOptionsAction: sqlOptions =>
                                    {
                                        sqlOptions.EnableRetryOnFailure(
                                        maxRetryCount: 10,
                                        maxRetryDelay: TimeSpan.FromSeconds(30),
                                        errorNumbersToAdd: null);
                                    })
                                    .EnableSensitiveDataLogging()
                                    .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
    }

    ...

así es como creo la configuración

var builder = new ConfigurationBuilder()
                  .SetBasePath(Directory.GetCurrentDirectory())
                  .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
configuration = builder.Build();

gracias por tu ayuda en esto

[edit]

aquí está la clase principal:

[Table("leads")]
public class Lead
{
    [Required]
    public int? Id { get; set; }

    [Required]
    public Company Company { get; set; }
    [Required]
    public User Contact { get; set; }
}

Pregunta hecha hace 3 años, 4 meses, 29 días - Por techtrailblazer


3 Respuestas:

  • Creo que para las propiedades de navegación para trabajar el núcleo de EF necesita FKs. Pero no estoy seguro de cómo funciona esto a través de la aplicación Web. Si es posible, pruebe con FKs como: [Table("leads")] clase pública Lead {} [Requirido] ¿Intenta pública? Id { get; set; }

        public int CompanyId { get; set; }
        public int UserId { get; set; }
    
        [Required]
        public Company Company { get; set; }
        [Required]
        public User Contact { get; set; }
    }
    

    Respondida el Dec 17, 2020 a las 12:09 - por binaryblossom

    Votos positivos: 0 | Votos negativos: 0

  • El problema que estás experimentando se debe a que en una aplicación de consola en C

    , no se realiza la carga perezosa (lazy loading) de manera predeterminada, al contrario de lo que ocurre en una aplicación web. Por lo tanto, debes realizar la carga explícita de las propiedades relacionadas que deseas incluir en tu consulta.

    Para corregir este problema, puedes utilizar el método Include() de Entity Framework para cargar las entidades relacionadas en tu consulta. Sin embargo, en una aplicación de consola, es recomendable utilizar IQueryable() en lugar de AsQueryable().

    Aquí te muestro cómo podrías hacerlo en tu código:

    csharp
    var context = new MyDBContext(configuration);
    var leads = context.Leads
        .Include(p => p.Company)
        .Include(p => p.Contact)
        .ToList();
    

    En cuanto a desactivar la carga perezosa (lazy loading), en lugar de utilizar LazyLoadingEnabled que no está disponible en Entity Framework Core, puedes lograrlo configurando la carga explícita (eager loading) a través del método Include(), tal como lo hiciste en el ejemplo anterior.

    Además, asegúrate de que en tu clase MyDBContext, estés utilizando using Microsoft.EntityFrameworkCore; para poder acceder a los métodos y propiedades necesarios.

    Por último, no olvides que en una aplicación de consola, en el método Main, debes instanciar adecuadamente tu MyDBContext y pasarle la configuración correspondiente para que la conexión a la base de datos funcione correctamente.

    Espero que esta información te haya sido útil. Si tienes alguna otra pregunta o necesitas más ayuda, no dudes en consultarme.

    Respondida el Dec 18, 2020 a las 12:14 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • Existen algunas diferencias clave entre las aplicaciones de consola y las aplicaciones web en cuanto a la configuración de Entity Framework.

    Carga diferida

    En las aplicaciones de consola, la carga diferida está habilitada de forma predeterminada. Esto significa que las propiedades de navegación, como Company y Contact, no se cargarán automáticamente cuando se recupere un objeto Lead. En cambio, se cargarán cuando se acceda a ellos por primera vez.

    En las aplicaciones web, la carga diferida está deshabilitada de forma predeterminada. Esto significa que las propiedades de navegación se cargarán automáticamente cuando se recupere un objeto Lead.

    Deshabilitar la carga diferida

    Para deshabilitar la carga diferida en una aplicación de consola, puede utilizar el método AsNoTracking en su consulta:

    csharp
    var leads = context.Leads.AsQueryable()
                                .Include(p => p.Company)
                                .Include(p => p.Contact)
                                .AsNoTracking()
                                .ToList();
    

    Esto evitará que EF cargue las propiedades de navegación automáticamente.

    Uso de LazyLoadingEnabled

    La propiedad LazyLoadingEnabled no está disponible en la clase DbContext en .NET Core. En su lugar, puede utilizar el método ChangeTracker.LazyLoadingEnabled para habilitar o deshabilitar la carga diferida:

    csharp
    context.ChangeTracker.LazyLoadingEnabled = false;
    

    Solución propuesta

    Para resolver el problema de que los datos incluidos son nulos en su aplicación de consola, puede intentar deshabilitar la carga diferida utilizando el siguiente código:

    csharp
    var leads = context.Leads.AsQueryable()
                                .Include(p => p.Company)
                                .Include(p => p.Contact)
                                .AsNoTracking()
                                .ToList();
    

    Esto debería cargar las propiedades de navegación inmediatamente y evitar el problema de los datos nulos.

    Respondida el Dec 18, 2020 a las 12:22 - por Gemini

    Votos positivos: 0 | Votos negativos: 0