2016-08-23 22 views
1

エンティティオブジェクトのプロパティとしてEnumを利用するEF 6の機能を利用しています。Entity Framework 6列挙型の非同期DBContextアクセス

私は非同期的基準の一部として、この列挙プロパティを使用してデータソースを照会しようとすると、クエリが返すことはありません。ただし、クエリを同期させると、正常に完了します。 EFによって生成されたSQLは、両方のケースで同じであり、正しいです。ここで

entity objectの簡易版:

public class RoleGroup { 
    public int Id { get; set; } 

    [Column("RequestSubTypeId")] 
    public SubTypeEnum? SubTypeId { get; set; } 
} 

ここに私のenumの簡易版です。

public enum SubTypeEnum { 
    AccountsPayableInquiry = 1, 
    PayrollInquiry = 2, 
    BillingInquiry = 3 
} 

ここで私は、データベースから役割グループを取得するために使用していますmethodは、ですsubTypeIdパラメータに基づいて:

public async Task<RoleGroup> GetRoleGroupBySubType(SubTypeEnum subTypeId) { 
    return await Context.WorkflowRoleGroups 
         .FirstAsync(roleGroup => roleGroup.SubTypeId == subTypeId); 
} 

Context.Database.Log = s => Debug.WriteLine(s);を使用して、私は、次のSQLは、上記の方法により製造されていることを確認することができるよ:

SELECT TOP (1) 
    [Extent1].[Id] AS [Id], 
    [Extent1].[RequestSubTypeId] AS [RequestSubTypeId] 
FROM [dbo].[WorkflowRoleGroups] AS [Extent1] 
WHERE [Extent1].[RequestSubTypeId] = @p__linq__0 

-- p__linq__0: '1' (Type = Int32, IsNullable = false) 

は、しかし、それは限り実行が取得するようです。何も起こらず、エラーはスローされません。出力ウィンドウで、「スレッドがコード0で終了しました」を参照してください。

このメソッドを同期させると、以下の例のように、正しい結果がデータベースから返され、すべて正常です。生成されるSQLクエリは、非同期クエリと同じです。

public RoleGroup GetRoleGroupBySubType(SubTypeEnum subTypeId) { 
    return Context.WorkflowRoleGroups 
        .First(roleGroup => roleGroup.SubTypeId == subTypeId); 
} 

基準の一部としてenumとで非同期を使用して、なぜ私が理解する上で任意の指導をいただければと思いますが、この問題が発生します。

+0

それはおそらくEFが、非同期/待つとコールスタック内(デッドロック*の原因となります*) 'Task.Result'のようなものとの混合の使用とは何かとは何の関係もありません。呼び出しスタック全体は、あらゆる点で非同期/待機を使用する必要があります(非同期とも呼ばれます)。呼び出しスタック内の他のコードをすべて見ることなく、デッドロックの原因となっている部分を知る方法はありません。 – Igor

+0

非常に興味深い。あなたは死んでいる。これを呼び出す同期メソッドは最後に '.Result'を持っていました。私は 'Task.Run(async()=> await GetRoleGroupBySubType(subTypeId))で非同期メソッド呼び出し全体をラップすることで簡単なテストを行いました。私は '.Result'がデッドロックを引き起こす理由についてもっと理解したいと思いますが、' Task.Run()。Result'はそれがありません。あなたは偶然、より多くの情報を得る良い情報源を知っていますか? p.s.あなたのコメントを答えさせて受け入れます。 – Sam

答えて

2

それはおそらくEFが、非同期/待つとコールスタック内(デッドロックが発生します)Task.Resultのようなものとの混合の使用とは何かとは何の関係もありません。呼び出しスタック全体は、あらゆる点で非同期/待機を使用する必要があります(非同期とも呼ばれます)。呼び出しスタック内の他のコードをすべて見ることなく、デッドロックの原因となっている部分を知る方法はありません。ここで

は、デッドロックがDon't Block on Async Codeを発生する可能性がありますなぜ/どのように理解するための良い情報源です。 Stephen Cleary(参照記事の著者)は、一般に、SOに関する非同期の質問にも応答します。

+1

素晴らしい - ありがとうございました! – Sam

関連する問題