¿Cómo manejar la vida útil del Marco de Entidades en un proceso de larga duración?

Estoy haciendo una herramienta de extracción de datos (.NET Core consola app) que procesará decenas de miles de archivos y escribirá datos extraídos a una base de datos. Sólo hay inserciones en el DB, no lecturas ni actualizaciones. Tengo la intención de ejecutar múltiples casos, todos escribiendo a la misma tabla.

Estoy usando Autofac para DI, e inyectando el Contexto DB de EF en una clase que salta a través de los archivos y escribe al DB.

Quiero mantener la vida de DB Context corto, pero no estoy seguro de cómo hacerlo con DI. ¿Hay algún tipo de operación "refresca" para renovar eficazmente el DBContext? ¿O debería inyectar una DBContextFactory y conseguir un nuevo DBContext para cada archivo procesado? (Y si es así, ¿cómo es la fábrica? ¿Construye explícitamente un nuevo DBContext?)

Pregunta hecha hace 3 años, 4 meses, 28 días - Por syntaxsavvy


3 Respuestas:

  • Si te aferras a la instancia inyectada de DbContext y la usas en un bucle, entonces claramente la vida de DbContext no puede ser corta.

    Como usted sugiere, use un Context Builder en el DI. Este es un ejemplo que crea un contexto de tipo T usando SQLServer:

    public class DbContextBuilder where T : DbContext
    {
        public readonly T Context;
        public DbContextBuilder(string connectionStringName)
        {
            IConfigurationBuilder cfgBuilder = new ConfigurationBuilder();
            cfgBuilder.AddJsonFile("appsettings.json");
            IConfiguration cfg = cfgBuilder.Build();
    
            DbContextOptionsBuilder optsBuilders = new DbContextOptionsBuilder();
            optsBuilders.UseSqlServer(cfg.GetConnectionString(connectionStringName));
            Context = (T)Activator.CreateInstance(typeof(T), optsBuilders.Options);
        }
    }
    

    y en cada bucle:

    foreach (var file in files)
    {
        using (DbContext ctx = new DbContextBuilder("{name of conn string in appsettings}").Context)
        {
            // Do you writes for the current file
        }
    }
    

    Respondida el Dec 18, 2020 a las 15:43 - por codeglitch

    Votos positivos: 0 | Votos negativos: 0

  • Para manejar la vida útil del DB Context en un proceso de larga duración, en tu caso de una herramienta de extracción de datos en una aplicación de consola .NET Core, hay varias opciones que puedes considerar:

    • Inyección de dependencias (DI) con ámbito por solicitud: Una forma común de manejar la vida útil del DB Context es configurar su ámbito de DI para que se cree y se inyecte por solicitud. Esto significa que cada vez que se necesite un DB Context en la misma solicitud, se reutiliza el mismo DB Context. Esto se puede lograr con Autofac configurando el ámbito del DB Context.
    • Inyección de dependencias con ámbito por proceso: Si necesitas un enfoque más a largo plazo para manejar la vida útil del DB Context, puedes configurar el ámbito de DI para que sea por proceso. Esto significa que se creará un único DB Context para toda la duración del proceso de la aplicación. Sin embargo, esto puede llevar a problemas de concurrencia si se intenta utilizar el mismo DB Context desde múltiples hilos al mismo tiempo.
    • Crear un nuevo DB Context explícitamente: Otra opción es crear un nuevo DB Context explícitamente para cada archivo procesado y luego deshacerse de él una vez que se complete el proceso. Puedes hacer esto a través de una fábrica de DB Context que se encargue de crear nuevas instancias del DB Context cuando sea necesario. Esto puede ser útil si quieres asegurarte de que no hay una referencia persistente al DB Context durante todo el proceso.
    • Refresh el DB Context: Sin embargo, Entity Framework Core no tiene un método "Refresh" para renovar eficazmente el DB Context. En su lugar, puedes deshacerte de un DB Context existente y crear uno nuevo cuando sea necesario.

    En resumen, para tu caso específico de un proceso de larga duración que procesará decenas de miles de archivos, te recomendaría configurar el ámbito del DB Context por solicitud o crear un nuevo DB Context explícitamente para cada archivo procesado y luego liberarlo. Separa claramente las responsabilidades entre la extracción de datos y la escritura en la base de datos para ayudar a mantener la lógica clara y evitar problemas de concurrencia.

    Respondida el Dec 19, 2020 a las 15:40 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • Manejo de la vida útil de DbContext en un proceso de larga duración

    1. Usar una fábrica DbContext

    Esta es la opción recomendada para procesos de larga duración. Crea una interfaz IDbContextFactory<TContext> y una implementación DbContextFactory<TContext> que cree nuevas instancias de DbContext.

    Ejemplo de fábrica de DbContext:

    csharp
    public interface IDbContextFactory where TContext : DbContext
    {
        TContext CreateDbContext();
    }
    
    public class DbContextFactory : IDbContextFactory where TContext : DbContext
    {
        public TContext CreateDbContext()
        {
            return new TContext();
        }
    }
    

    2. Inyectar la fábrica DbContext en el servicio

    En lugar de inyectar directamente DbContext, inyecta la IDbContextFactory<DbContext> en el servicio que necesita acceso a la base de datos.

    Ejemplo de inyección de fábrica de DbContext:

    csharp
    public class DataExtractionService
    {
        private readonly IDbContextFactory _dbContextFactory;
    
        public DataExtractionService(IDbContextFactory dbContextFactory)
        {
            _dbContextFactory = dbContextFactory;
        }
    
        public void ProcessFile(string filePath)
        {
            using (var dbContext = _dbContextFactory.CreateDbContext())
            {
                // Usar dbContext para escribir datos en la base de datos
            }
        }
    }
    

    3. Crear un nuevo DbContext para cada archivo

    Cada vez que se procesa un archivo, crea una nueva instancia de DbContext mediante el método CreateDbContext() de la fábrica. Esto garantiza que el DbContext tenga una vida útil corta y recursos liberados después de procesar cada archivo.

    Beneficios de usar una fábrica DbContext:

    Proporciona un punto de control centralizado para crear instancias de DbContext. Permite que la vida útil de DbContext sea gestionada explícitamente. * Simplifica el código y promueve la encapsulación.

    Respondida el Dec 19, 2020 a las 15:53 - por Gemini

    Votos positivos: 0 | Votos negativos: 0