【问题标题】:Asynchronous Operations with Entity Framework实体框架的异步操作
【发布时间】:2015-10-28 13:26:24
【问题描述】:

我正在开发一个应用程序,它需要接收对象列表并根据数据库值验证它们的属性,以确保一切都有效。但是,可能有许多具有许多属性的对象需要验证。

我最初的想法是为每个验证操作创建一个辅助方法,每个都打开一个到数据库上下文的连接,执行它们所需的选择语句,然后返回适当的数据。

foreach 循环中的最后一个操作是等待所有操作,然后移动到下一个对象。

但是,我最初使用 FirstOrDefaultAsync 的尝试被证明是徒劳的,因为它似乎从不返回值,而且它似乎与 Linq to SQL 不兼容。那么我还有哪些其他选项可以使这些辅助方法异步呢?

我的主要方法如下所示:

public async Task<List<BulkUserResponse.VerifiedUser>> ValidateBulkUsers(BulkUserResponse userList)
{
    var users = userList.UserList;

    foreach (var user in users)
    {
        var userGlobalLogin = VerifyGlobalLogin(user.GlobalLogin);
        // other variables and helper methods

        await Task.WhenAll(userGlobalLogin);

        user.GlobalLogin = userGlobalLogin.Result;
        // other properties and helper method assignment
    }

    return users;
}

使用如下所示的辅助方法之一:

public async Task<BulkUserResponse.GlobalLogin> VerifyGlobalLogin(BulkUserResponse.GlobalLogin login)
{
    using (var context = new DbContext())
    {
        var userExists = await context.GlobalLogins.FirstOrDefaultAsync(n => n.LoginName == login.Value) == null;
        login.Valid = userExists;
        login.VerificationMessage = (userExists ? "" : "Login already exists.");

        return login;
    }
}

辅助方法最初看起来像:

public async Task<BulkUserResponse.GlobalLogin> VerifyGlobalLogin(BulkUserResponse.GlobalLogin login)
{
    using (var context = new DbContext())
    {
        var userExists = context.GlobalLogins.FirstOrDefault(n => n.LoginName == login.Value) == null;
        login.Valid = userExists;
        login.VerificationMessage = (userExists ? "" : "Login already exists.");

        return login;
    }
}

【问题讨论】:

  • 你能展示你的代码使用情况吗?
  • 是 Linq2Sql 还是 EF?
  • 我已经用代码示例更新了我的初始帖子。
  • 不确定这是否是一个问题(以及以下是否是解决方案),但尝试自己进行查询(以获取对象),然后将其与 null 进行比较。
  • 这不是很奇怪。之后它立即开始工作。

标签: c# entity-framework linq asynchronous


【解决方案1】:

它似乎与 Linq to SQL 不兼容。

LINQ to SQL 不支持异步查询。但是,如果您可以升级到 Entity Framework,则可以使用它。

我最初使用 FirstOrDefaultAsync 的尝试被证明是徒劳的,因为它似乎永远不会返回值

正如我在博客中所描述的,most common cause of this deadlock 是调用堆栈更靠前的代码阻塞了任务(通常通过调用WaitResult)。最正确的解决方案是将那些阻塞调用改为使用await

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-16
    相关资源
    最近更新 更多