2017-08-27 14 views
1

ASP.NET MVC Webサイトでは、ユーザーがブックを参照します。彼らは自分自身で作成したリストに各書籍を追加することができます。外部DbContext呼び出し中のEF DbContextの内部呼び出し非同期動作ASP.NET MVC

ユーザーが書籍を閲覧すると、各書籍の下にすべてのリストがドロップダウン表示され、書籍を追加することができます。これまでのところ良いことだが、私が今したいのは、書籍が既にユーザーのリストの1つに含まれているかどうかを知ることです。

これは、関連のviewmodelです:

public class UserBookListsMinimalVM { 
    public int ListId { get; set; } 
    public string ListName { get; set; } 
    public bool BookAlreadyInList { get; set; } 
} 

そして、これは私がアイテムを取得するために実行クエリです:

var userBookLists = await context.vwUserBookLists 
           .Where(x => x.ListOwner == userName) 
           .Select(x => new UserBookListsMinimalVM 
           { 
            ListId = x.ListId, 
            ListName = x.ListName, 
            BookAlreadyInList = context.List_Books.Any(y => y.ListId == x.ListId && y.BookId == bookId) 
           }) 
           .OrderBy(x => x.ListName) 
           .ToListAsync(); 

vwUserBookListsは、リスト関連の情報やList_Bookを含むビューが仲介ですリストと本の間の表(リストごとの本など)。

EFで生成されたSQLは、ステートメントのネストされており、主にBookAlreadyInListプロパティを考慮しています。 (私は、クエリを簡素化することができるかどうかわからない、私は提案を開いてる)

は、それがawait編ではありません見て、BookAlreadyInList割り当て中contextへの呼び出しは関数全体の非同期を「壊す」していますか?

+1

このコードで予期しない動作が発生しましたか?何か動作していないのですか?具体的に何を求めているのかは分かりません。 '.Any()'の呼び出しは非同期ではないので、待つ必要はありません。 – David

+0

こんにちは@David - 正常に動作します(つまり、意図したとおりに結果を返します)。私の質問は、 'BookAlreadyInList'の割り当て中の' context'への非同期呼び出しが、 'await context'外部非同期呼び出しと競合するかどうかです。 '.Any()'は '.AnyAsync()'になるべきですか? – globetrotter

+1

私は '.AnyAsync()'はありませんと思いますが(すぐにテストすることはできますが)。 '.Any()'はデータソースから何も実際には実現しないので、本当に必要はありません。他のLINQメソッドと同様に、バッキングデータストアの式ツリーに変換されます。データ( '.ToList()'のような)を実際に実現するメソッドだけが非同期バージョンを必要とします。 – David

答えて

2

ToListAsync()がジョブの実行を完了すると、非同期操作が中断されることはありません。その前に何も壊れていない非同期操作が1つだけあります。クエリ内で何をしていても、await/async契約は尊重されます。たとえば、同期ToList()を呼び出すと、その内部のいくつかのエンティティをマテリアライズしようとしても(EFがこれを許容していると仮定して)、この同期呼び出しはバックグラウンドスレッドで行われます。クエリ内でAnyAsyncを使用することはできません。これは、SQLプロバイダがSQL Serverではなくc#に固有の非同期操作を変換できないためです。

さらに重要なのは、EFがデータベースに1つのクエリしか送信していないか、またはクエリを複数のデータベース呼び出しに変換しているかどうかを依頼することができます(使用しているバージョンによって)、またはメモリ内でいくつかの操作を行うことさえできます。正確に何が起こっているかを知る最も良い方法は、生成されたSQLを見ることができる場合は出力ウィンドウを、コードを実行している間はSQLプロファイラを起動してデータベースを監視することです。 .netコアの最新バージョンでは、式ツリーを完全にsqlに変換できない場合や、メモリ内で操作を行う必要がある場合に、例外をスローするようにdbcontextを構成できます。そうしないと、出力ウィンドウに警告が表示されます。

関連する問題