【问题标题】:Entity Framework 6 Async DBContext Access with EnumsEntity Framework 6 Async DBContext Access with Enums
【发布时间】:2016-08-23 19:36:51
【问题描述】:

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

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

这是我用来根据 subTypeId 参数从数据库中检索角色组的method

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

使用Context.Database.Log = s =&gt; 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 in 作为标准的一部分会导致此问题,我将不胜感激。

【问题讨论】:

  • 它可能与 EF 无关,但与您使用 async/await 并将其与 Task.Result 之类的东西混合使用有关(这将导致死锁)在调用堆栈中。整个调用堆栈应该在每一点都使用 async/await(也一直称为 async)。如果不查看调用堆栈中的所有其他代码,就无法知道是什么部分导致了死锁。
  • 非常有趣。你死定了。调用它的同步方法最后有.Result。我通过将整个异步方法调用包装在Task.Run(async () =&gt; await GetRoleGroupBySubType(subTypeId)).Result 中进行了快速测试,并且它没有问题地工作。我想更多地了解为什么.Result 会导致死锁,但Task.Run().Result 不会。您是否偶然知道获取更多信息的良好来源? p.s.让您的评论成为答案,我会接受。

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


【解决方案1】:

它可能与 EF 无关,但与您使用 async/await 并将其与调用堆栈中的 Task.Result(这将导致死锁)之类的东西混合有关。整个调用堆栈应该在每一点都使用 async/await(也一直称为 async)。如果不查看调用堆栈中的所有其他代码,就无法知道是什么部分导致了死锁。

这是了解为什么/如何发生死锁Don't Block on Async Code 的一个很好的来源。 Stephen Cleary(参考文章的作者)也经常回答关于 SO 的 async-await 问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-04
    • 2014-08-07
    • 2020-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-18
    • 2014-11-12
    相关资源
    最近更新 更多