亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

多線程 API 應用程序中的 EF 核心 DbContext

多線程 API 應用程序中的 EF 核心 DbContext

C#
至尊寶的傳說 2022-12-24 10:09:22
tl;dr如何在多線程 .NET Core API 應用程序中使用 Entity Framework,即使 DbContext 不是線程安全的?語境我正在開發一個 .NET Core API 應用程序,它公開了幾個訪問數據庫并從中讀取數據的 RESTful 接口,同時運行多個 TimedHostedServices 作為后臺工作線程,定期從其他 Web 服務輪詢數據并將它們存儲到數據庫中。我知道 DbContext 不是線程安全的。我在 Stackoverflow 上閱讀了很多文檔、博客文章和答案,我可以找到很多(部分矛盾的)答案,但在使用 DI 時沒有真正的“最佳實踐”。我試過的東西ServiceLifetime.Scoped通過擴展方法使用默認值AddDbContext會由于競爭條件而導致異常。我不想使用鎖(例如信號量),因為明顯的缺點是:代碼被鎖污染,try/catch/finally 安全釋放鎖它看起來并不“穩健”,即當我忘記鎖定訪問 DbContext 的區域時。在處理同時處理并發連接和訪問的數據庫時,在應用程序中人為同步數據庫訪問似乎是多余的和“不自然的”不是注入MyDbContext而是DbContextOptions<MyDbContext>僅在我需要訪問數據庫時構建上下文,using在讀/寫之后使用語句立即處理它似乎有很多資源使用開銷和不必要的許多連接打開/關閉。題我真的很困惑:這怎么能實現?我不認為我的用例是超級特殊的——從后臺工作人員填充數據庫并從 Web API 層查詢它——所以應該有一種有意義的方法來使用 ef 核心來完成這項工作。非常感謝!
查看完整描述

2 回答

?
互換的青春

TA貢獻1797條經驗 獲得超6個贊

您應該在TimedHostedServices觸發時創建一個范圍。


在構造函數中注入服務提供者:


public MyServiceService(IServiceProvider services)

{

    _services = services;

}

然后在任務觸發時創建一個范圍


using (var scope = _services.CreateScope())

{

    var anotherService = scope.ServiceProvider.GetRequiredService<AnotherService>();


    anotherService.Something();

}

文檔中提供了更完整的示例



查看完整回答
反對 回復 2022-12-24
?
冉冉說

TA貢獻1877條經驗 獲得超1個贊

另一種創建自己的 DbContextFactory 并為每個查詢實例化新實例的方法。


public class DbContextFactory

{

    public YourDbContext Create()

    {

        var options = new DbContextOptionsBuilder<YourDbContext>()

            .UseSqlServer(_connectionString)

            .Options;


        return new YourDbContext(options);

    }

}

用法


public class Service

{

    private readonly DbContextFactory _dbContextFactory;


    public Service(DbContextFactory dbContextFactory) 

         => _dbContextFactory = dbContextFactory;


    public void Execute()

    {

        using (var context = _dbContextFactory.Create())

        {

            // use context

        }

    }

}    

使用工廠,您無需再擔心范圍,并使您的代碼擺脫 ASP.NET Core 依賴項。

您將能夠異步執行查詢,這對于沒有變通辦法的范圍 DbContext 是不可能的。

您始終對調用時保存的數據充滿信心.SaveChanges(),其中使用作用域 DbContext 可能會在其他類中更改某些實體。


查看完整回答
反對 回復 2022-12-24
  • 2 回答
  • 0 關注
  • 317 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號