2

私はEF7でAsp.net 5/Core 1アプリケーションを持っています。私はDbContextをDIコンテナに通常登録します。asp.netコアとef7の並列メソッドで注入DbContextを使用するには?

services.AddEntityFramework().AddSqlServer() 
    .AddDbContext<MyDbContext>(options => options.UseSqlServer(connection)); 

ここには、私が何をしようとしているかを示す小さなサンプルがあります。

public class MyController : Controller 
{ 
    MyDbContext _myDbContext; 

    public MyController(MyDbContext myDbContext) 
    { 
     _myDbContext = myDbContext; 
    } 

    public IActionResult Index() 
    { 
     //Just start these and don't wait for them to finish 
     //We don't care if they succeed or not 
     Task.Run(() => DoSomeLogging1()); 
     Task.Run(() => DoSomeLogging2()); 

     return View(); 
    } 

    private void DoSomeLogging1() 
    { 
     _myDbContext.Items.ToList(); 
    } 

    private void DoSomeLogging2() 
    { 
     _myDbContext.Items.ToList(); 
    } 
} 

両方のDoSomeLoggingXメソッドは、コントローラに注入されたMyDbContextインスタンスを使用します。メソッドは同時にdbクエリを同時に実行するので、他のクエリは常に失敗します

接続が閉じられていません。接続の現在の状態は 接続です。

MyDbContextでも参照を取得するためにDIが使用されているため、必要な場合でも直接使用することはできません。

コードを並行して実行しても、エンティティフレームワークを使用してデータベースを使用するにはどうすればよいですか?

+0

アクション全体のコードを表示できますか?あなたは仕事が終わるのを待っていないようです。 – Thomas

+3

まず最初に、ASP.NETでバックグラウンドスレッドを生成しないでください。これは非常に悪いことです。 ASP.NETアプリケーションの場合、スレッドは最も重要なリソースです。非同期操作を行う場合は、await/asyncを使用する必要があります。これにより、非同期操作が完了するまでスレッドが解放されます。 CPUに敏感な操作で**リクエストスレッド**で処理された場合は、新しいスレッドを開始しないでください。 ASP.NETのDbContextは、既定で有効範囲として登録されています。つまり、要求の期間中、DbContextが解決され、有効期間が延長されます。リクエストが終了すると、リクエストが破棄されます。 – Tseng

+1

実際にいくつかのロギングを行い、すぐに戻る場合は、ログイベントを発生させ、メッセージバスにキューイングされ、より長い寿命を持つdbcontextを持つサービスによって処理される、何らかの種類のメッセージバスを使用する必要がありますつまり、アプリケーションの存続期間)、そこでのログ処理、または分散アーキテクチャ(rabbitmqや他のAMQPシステム)を使用し、別のプロセスでキューからメッセージを取得して処理した場合 – Tseng

答えて

1

忘れログと-アプローチをサポートしてNLogのようなロギングフレームワークを使用します私もこの問題に直面していましたが、今は私の一時的なソリューション EF 7 (Core). Create DBContext like AddTransient

誰かがより洗練されたソリューションを提供できる場合は、私は感謝します。時々私は本当にユーザーに即時の結果を返す必要があり、そのような場合には/ asyncは適合しません。

0

簡単な回答:できません。 EFはパラレルSQLの実行のために作られていません(それは決してありません)。

あまり簡単ではありません。おそらくこれは、(@Tsengは彼のコメントにポイントを作った)あなたの問題にアプローチする正しい方法ではありませんが、あなたができることのようなログものを行う必要がある場合:

  • 2回のロギングアクションシーケンシャルとシェアを作ります同じEFインスタンス
  • (並列処理と完璧に動作します)SqlConnectionオブジェクトで使用する、昔ながらのSQLを - そしてそれは高速です