简体   繁体   English

如何在长时间运行的过程中处理实体框架的生命周期?

[英]How to handle Entity Framework lifetime in a long-running process?

I am making a data extraction tool (.NET Core console app) that will process tens of thousands of files and write extracted data to a database.我正在制作一个数据提取工具(.NET Core 控制台应用程序),它将处理数万个文件并将提取的数据写入数据库。 There are only insertions to the DB, no reads or updates.只有插入数据库,没有读取或更新。 I intend to run multiple instances, all writing to the same table.我打算运行多个实例,所有实例都写入同一个表。

I am using Autofac for DI, and injecting the EF DB Context into a class that loops through the files and writes to the DB.我将 Autofac 用于 DI,并将 EF DB 上下文注入到 class 中,该 class 循环遍历文件并写入数据库。

I want to keep the DB Context lifetime short, but am not sure how to do that with DI.我想保持 DB Context 的生命周期很短,但我不确定如何使用 DI 来做到这一点。 Is there some kind of "refresh" operation to effectively renew the DBContext?是否有某种“刷新”操作来有效地更新 DBContext? Or should I inject a DBContextFactory and get a new DBContext for each file processed?或者我应该注入一个 DBContextFactory 并为每个处理的文件获取一个新的 DBContext? (And if so, what does the factory look like? Does it explicitly construct a new DBContext?) (如果是,工厂是什么样子的?它是否显式地构造了一个新的 DBContext?)

If you're holding on to the injected instance of DbContext and using it in a loop, then clearly the lifetime of DbContext cannot be short.如果您持有注入的 DbContext 实例并在循环中使用它,那么显然 DbContext 的生命周期不会很短。

As you suggest, use a Context Builder in the DI.正如您所建议的,在 DI 中使用 Context Builder。 Here's an example that creates a context of type T using SQLServer:下面是一个使用 SQLServer 创建类型 T 的上下文的示例:

public class DbContextBuilder<T> where T : DbContext
{
    public readonly T Context;
    public DbContextBuilder(string connectionStringName)
    {
        IConfigurationBuilder cfgBuilder = new ConfigurationBuilder();
        cfgBuilder.AddJsonFile("appsettings.json");
        IConfiguration cfg = cfgBuilder.Build();

        DbContextOptionsBuilder<T> optsBuilders = new DbContextOptionsBuilder<T>();
        optsBuilders.UseSqlServer(cfg.GetConnectionString(connectionStringName));
        Context = (T)Activator.CreateInstance(typeof(T), optsBuilders.Options);
    }
}

and in each loop:在每个循环中:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM