【发布时间】: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 => 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 () => await GetRoleGroupBySubType(subTypeId)).Result中进行了快速测试,并且它没有问题地工作。我想更多地了解为什么.Result会导致死锁,但Task.Run().Result不会。您是否偶然知道获取更多信息的良好来源? p.s.让您的评论成为答案,我会接受。
标签: c# entity-framework asynchronous enums entity-framework-6