实体框架6使用枚举进行异步DBContext访问

时间:2016-08-23 19:36:51

标签: c# entity-framework asynchronous enums entity-framework-6

我正在利用EF 6的能力将Enum作为实体对象中的属性。

当我尝试使用此枚举属性作为条件的一部分异步查询数据源时,查询永远不会返回。但是,如果我同步进行查询,则会成功完成。 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中使用async作为标准的一部分会导致此问题。

1 个答案:

答案 0 :(得分:2)

它可能与EF无关,但与使用async / await和将其与调用堆栈中的Task.Result(会导致死锁)等混合有关。整个调用堆栈应该在每个点使用async / await(也称为async)。在没有看到调用堆栈中的所有其他代码的情况下,无法知道哪个部分导致死锁。

这是了解死锁发生原因/方式Don't Block on Async Code的良好来源。 Stephen Cleary(引用文章的作者)也常常回应异步 - 等待SO上的问题。