使用包含实体框架核心3.1时如何过滤嵌套对象

时间:2020-02-05 20:04:14

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

我有一个 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 <3.0中,我可以这样做

 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表达式无效

2 个答案:

答案 0 :(得分: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,因此我们根本不需要分配它。如果我们获取多个用户数据,则效果很好。

答案 1 :(得分:0)

一个选项是:

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)