繁体   English   中英

在这种情况下,如何防止在上下文中进行第二次操作?

[英]How to prevent second operation on context in this case?

我有这样的代码:

它从资料库,在“自定义”谓词加载数据Where

这必须询问数据库有关确定真/假的权限

public List<User> getUsersWhoCanDoSomething()
{
    return _context
            .Users
            .Where(x => CanPerformAction(user))
            .Take(10000)
            .OrderByDescending(x => x.CreationDate)
            .ToList();
}

private bool CanPerformAction(User user)
{
    var permission = _context
    .Permissions
    .FirstOrDefault(x => x.Name == user.Permissions.Name)
    .Level;

    return permission > 5;
}   

如何更改此代码以防止出现此异常:

A second operation started on this context before a previous operation completed.

解:

移动Where / Filter出来的LINQ链

public List<User> getUsersWhoCan...()
{
    var users = _context
            .Users
            .Include(x => x.Permissions)
            .Take(10000)
            .OrderByDescending(x => x.CreationDate)
            .ToList();

    var tempList = new List<User>();

    foreach (var user in users)
    {
        if (CanPerformAction(user))
        {
            tempList.Add(user);
        }
    }

    return tempList;
}

问题的根源在于,一次只能将DbContext对象用于一个查询。 CanPerformActiongetUsersWhoCanDoSomething执行期间执行了自己的数据库调用(由于FirstOrDefault )。 这就是为什么您要获得例外。

您的答案会奏效,但您要获取的数据超出了您的期望,然后丢弃了一些数据。 如果您的用户数超过10,000,则可能会因此而丢失一些用户(因为Take(10000) )。

这应该做同样的事情(我想-我不知道您的确切数据库架构)。 它将条件合并到查询中,因此您仅获得所需的数据。

return _context
        .Users
        .Where(u => u.Permissions.Any(l => l.Level > 5))
        .Take(10000)
        .OrderByDescending(x => x.CreationDate)
        .ToList();

执行同一操作的另一种方法是仍然使用单独的方法(从技术上讲=>之后的任何东西在任何情况下都是单独的方法),但不要引用_contextFirstOrDefault (这会触发单独的db调用)。 如果使用.Where(x => CanPerformAction(user)) ,这将与我的代码完全相同。

private bool CanPerformAction(User user)
{
    return user.Permissions.Any(l => l.Level > 5);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM