【问题标题】:How to filter nested object when using include Entity Framework core 3.1使用include Entity Framework core 3.1时如何过滤嵌套对象
【发布时间】:2020-02-05 20:04:14
【问题描述】:

我有一个 user 表,其中包含一个名为 UserPriviliges 的嵌套表,我有一个 isDeleted 字段来识别已删除的数据而不实际删除它,我想使用 include 检索具有其权限的用户

 public async Task<User> GetUser(Guid userId)
    {
        return await RepositoryContext.Users
            .Include(x => x.UserPrivileges).ThenInclude(x => x.Privilege)
            .FirstOrDefaultAsync(x => x.Id == userId);
    }

如何过滤 UserPriviliges 以仅带入具有错误 isDeleted 属性的项目

在 EF Core

 return await RepositoryContext.Users
            .Include(x => x.UserPrivileges.Where(y=>y.IsDeleted)).ThenInclude(x => x.Privilege)
            .FirstOrDefaultAsync(x => x.Id == userId);

但它在返回的 EF Core 3.1 中不再工作

Include 中使用的 Lambda 表达式无效

【问题讨论】:

    标签: c# entity-framework asp.net-core asp.net-core-3.1 entity-framework-core-3.1


    【解决方案1】:

    我根本不记得这在 EF Core 中工作;通常我们会将其分为两个查询:1- 获取用户数据,2- 获取过滤后的用户权限

    var user = await RepositoryContext.Users
        .FirstOrDefaultAsync(u => u.Id == userId);
    
    await RepositoryContext.UserPrivileges
        .Where(up => up.UserId == userId && !up.IsDeleted)
        .Include(up => up.Privilege)
        .ToListAsync();
    
    return user;
    

    当我们使用第二个查询将相关数据带入上下文时,ef 将负责填充 user.UserPrivileges,因此我们根本不需要分配它。如果我们获取多个用户数据,这很有效。

    【讨论】:

    • 感谢这项工作,虽然这不会增加对数据库的请求吗?
    • 是的,确实如此,因此您最终会收到 2 个请求,但它们的连接数较少。
    【解决方案2】:

    一个选项是:

    public async Task<User> GetUser(Guid userId)
    {
        return await RepositoryContext.Users
            .Include(x => x.UserPrivileges).ThenInclude(x => x.Privilege)
            .Where(x => x.UserPrivileges.Any(p => p.IsDeleted)) 
            .FirstOrDefaultAsync(x => x.Id == userId);
    }
    

    但这将返回具有所有 UserPrivileges 的用户(意味着返回的 User 对象将同时包含 IsDeleted 和 !IsDeleted UserPrivileges )。

    如果您在 UserPrivileges 中有用户引用,那么另一个选项是从 UserPrivileges 导航,如下所示:

    RepositoryContext.UserPrivileges
            .Include(x => x.User)
            .Where(x => x.IsDeleted && x.User.Id == userId)
    

    【讨论】:

    • 我在询问之前尝试了第一个,正如你所说,它返回所有权限,所以这不是一个解决方案,第二个对我不起作用,因为它会返回权限模型而不是用户模型和其中的权限,我需要用户模型,因为其中还有其他列表也需要返回,所以这对我没有用
    • 那么在返回用户对象之前(使用第一个选项),你需要做类似user.UserPrivileges = user.UserPrivileges.Where(p =&gt; p.IsDeleted)然后返回这个用户。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-30
    • 2018-11-02
    • 2020-06-07
    • 1970-01-01
    • 2021-10-19
    • 2020-03-23
    • 1970-01-01
    相关资源
    最近更新 更多