简体   繁体   English

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

[英]How to filter nested object when using include Entity Framework core 3.1

I have a user table that contains a nested table named UserPriviliges in this table I have isDeleted field to identify deleted data without actually deleting it, I want to retrieve a user with its privilege using include我有一个用户表,其中包含该表中名为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);
    }

how to filter UserPriviliges to bring only items with false isDeleted property如何过滤UserPriviliges以仅带 false isDeleted属性的项目

in EF Core <3.0 I could do it like this在 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);

but its not working any more in EF Core 3.1 it returns但它在 EF Core 3.1 中不再工作,它返回

Lambda expression used inside Include is not valid Include 中使用的 Lambda 表达式无效

I don't remember this working in EF Core at all;我根本不记得这在 EF Core 中工作过; and usually we would separate this into two queries: 1- fetch the user data, 2- fetch the filtered user privileges通常我们会将其分为两个查询: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;

When we bring related data into the context with the 2nd query, ef will take care of populating user.UserPrivileges, so we don't need to assign it at all.当我们使用第二个查询将相关数据带入上下文时,ef 将负责填充 user.UserPrivileges,因此我们根本不需要分配它。 This works well if we fetch multiple user data.如果我们获取多个用户数据,这很有效。

One option is :一种选择是:

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);
}

But this will return user with all the UserPrivileges (meaning returned User object will contain both IsDeleted and !IsDeleted UserPrivileges ).但这将返回具有所有 UserPrivileges 的用户(意味着返回的 User 对象将包含 IsDeleted 和 !IsDeleted UserPrivileges )。

if you have User reference in UserPrivileges, then another option is navigate from UserPrivileges something like below:如果您在 UserPrivileges 中有 User 引用,则另一个选项是从 UserPrivileges 导航,如下所示:

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

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

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