【问题标题】:How is Entity Framework Core with Dependency Injection disposed?具有依赖注入的 Entity Framework Core 是如何处理的?
【发布时间】:2020-01-28 09:58:34
【问题描述】:

在 Entity Framework Core 中,您通常会使用这样的东西,它应该适用于几乎所有情况:

using (var dbContext = new MyDbContext()) {
    await dbContext.Entities.WhereAsync(e => e.Something == somethingElse);
    await dbContext.SaveChangesAsync();
}

您还可以将依赖注入与数据库上下文一起使用。现在您可以将数据库上下文添加到 DI 容器中,并将其注入到您需要的类/控制器/构造器/方法中:

IHostBuilder builder = new HostBuilder()
    .ConfigureServices((context, collection) => {
        string connectionString = context.Configuration.GetConnectionString("MyDatabase");
        collection.AddDbContext<MyDbContext>();

...

public class Foo {
    public Foo(MyDbContext dbContext) { }
}

但是,将它注入到类/构造函数中,您通常会将实例保留为局部变量,这很公平,但不再有任何可能使用 using 语句。现在两种不同的方法最终可能会同时使用同一个 dbContext,这很可能会导致并发问题。

如果 dbContext 没有被注入,而只是在 using 语句中使用,那么并发应该没有问题,并且对象将在每个方法的末尾被释放。

那么您将如何正确处理并发和使用 Entity Framework Core 和依赖注入进行处置?

【问题讨论】:

  • AddTransient 或 AddScoped 到 DI 时并发有什么问题?

标签: c# dependency-injection entity-framework-core


【解决方案1】:

默认情况下扩展方法AddDbContext做:

services.AddScoped<MyDbContext>()

所以在AddDbContext 的情况下,将为每个请求创建一个新实例,并在工作完成后释放(请求中的对象相同,但不同请求中的对象不同)。所以,这里的并发应该没有任何问题。

如果您需要为每个控制器和每个服务创建一个新实例,您还可以将上下文作为瞬态添加到 DI。

【讨论】:

  • 那么你基本上不应该使用带有 dbcontext 的构造函数注入,因为这样可以同时从不同的地方调用同一个实例?这意味着数据库上下文的 DI 主要用于特定方法,而不是类?
  • 不,绝对不。建议在构造函数中使用 dbcontext 并将其解析为作用域。请参阅文档:docs.microsoft.com/ru-ru/aspnet/core/fundamentals/…
  • 我在该链接中看不到任何建议您应该为 EF 使用构造函数注入。
  • 你应该使用你想要的whatevent。如果您不想关心上下文生命周期,那么让 DI 来完成它并使用构造函数。如果要控制上下文的生命周期,请在 using 块中手动创建实例。创建和处置许多(每次方法运行时)对象可能会影响性能。
猜你喜欢
  • 1970-01-01
  • 2019-07-02
  • 2018-08-27
  • 2012-10-02
  • 2022-01-27
  • 2022-01-01
  • 2019-05-23
  • 1970-01-01
  • 2020-12-02
相关资源
最近更新 更多