簡體   English   中英

實體框架 DbContext 不使用依賴注入進行處置

[英]Entity Framework DbContext is NOT disposed using dependency injection

我在解決方案中有以下設置:

編輯:演示解決方案可以在這里找到

ASP.NET Core Web API:

public class MyController : ControllerBase
{
    private readonly IMyService _service;
    public MyController(IMyService service)
        {
             _service = service;
        }
}

服務層:

public class MyService: IMyService, IDisposable
{
    private readonly IDataContext _context;
    public MyService(IDataContext context)
        {
             _context = context;
        }
}

實體框架核心:

public class DataContext : DbContext, IDataContext, IDisposable
{
    public DataContext(DbContextOptions<DataContext> options, IAuthenticationService authentication, ILogger<DataContext> logger) : base(options) 
        {
            ...
        }
}

使用 Microsoft.Extensions.DependencyInjection 將所有內容鏈接在一起的“CompositionRoot”:

services.AddDbContext<DataContext>(options =>  options.UseSqlServer(configuration.GetConnectionString("myConnection")), ServiceLifetime.Transient);
services.AddTransient<IMyService, MyService>();
//EDIT: removed this line
//services.AddTransient<IDataContext, DataContext>(); 

這一切都按預期工作,但我的 DataContext 從未被處置。 我在 dispose 方法中添加了日志來監視此行為,但我無法弄清楚為什么會發生這種情況(或者在這種情況下不會發生)。 我試過了

  • 重新排序“AddTransient”但沒有成功(如預期的那樣)
  • 使用“AddScoped”而不是“AddTransient”

我在我的單元測試中使用一個接口來模擬 DbContext,但我希望我的 DbContext 被處理。 任何人都知道為什么會發生這種情況以及如何解決它?

編輯:一些額外的日志

  • 2020-03-24 21:09:29.5727|在 DataContext 中注入的選項
  • 2020-03-24 21:09:29.6064|在 DataContext 中注入的身份驗證
  • 2020-03-24 21:09:29.6064|在 DataContext 中注入的記錄器
  • 2020-03-24 21:09:29.6262| 創建數據上下文 1ddd98a1-a8f9-4096-8a11-c0b4d40d01ae
  • 2020-03-24 21:09:30.1918|記錄器注入客戶服務
  • 2020-03-24 21:09:30.2200|DataContext 注入 CustomerService
  • 2020-03-24 21:09:30.2300|在客戶服務中注入映射器
  • 2020-03-24 21:09:30.2482|在 CustomerService 中注入的身份驗證
  • 2020-03-24 21:09:30.2482| 創建客戶服務 5b446267-d908-4291-9918-af1841324708
  • 2020-03-24 21:09:30.2769|在 CustomerController 中注入的記錄器
  • 2020-03-24 21:09:30.2769|CustomerService 在 CustomerController 中注入
  • 2020-03-24 21:09:30.3186|CustomerController.GetCustomer(4)
  • 2020-03-24 21:09:35.0599| 處理 CustomerService 5b446267-d908-4291-9918-af1841324708

編輯 3 月 25 日:我嘗試使用沒有接口的 DataContext,但問題仍然存在。 我真的不知道我做錯了什么!

您沒有正確注冊 DbContext

使用AddDbContext的以下重載

services.AddDbContext<IDataContext, DataContext>(options =>  
    options.UseSqlServer(configuration.GetConnectionString("myConnection")));

這將使接口/抽象與具體實現相關聯。

並刪除臨時注冊

services.AddTransient<IDataContext, DataContext>();

也面臨這個問題(它實際上是問題嗎?)。 我有 ASP.Net Core WebApi 項目(框架 = net 5.0)並使用AddDbContext將其注入 MVC-Controller。 根據文章,它應該將 db-context 添加為“Scoped”。 根據我的期望,在這種情況下,db-context 應該根據每個 http 請求(就是這樣)進行實例化,並在 MVC-Controller 生命周期的范圍內隱式處理 - 但由於某種原因它不會發生.. 可能會導致在“無法跟蹤實體類型 {} 的實例,因為已經在跟蹤另一個具有鍵值 {} 的實例。 ”(這是我來這里的原因)

我相信,它可以通過在代碼中添加“使用”結構或從控制器調用 Dispose() 來修復

protected override void Dispose(bool disposing = true)
        {
            Console.WriteLine("Controller dispose.");
            _dbContext.Dispose(); //your db-context (injected in controller)
            base.Dispose(disposing);
        }

但不確定這是正確的解決方案..

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM