Как отфильтровать вложенный объект при использовании ядра Entity Framework 3.1 - PullRequest
3 голосов
/ 05 февраля 2020

У меня есть таблица 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 Я мог бы сделать это следующим образом </p>

 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, недопустимо

Ответы [ 2 ]

1 голос
/ 06 февраля 2020

Я вообще не помню, чтобы это работало в 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, поэтому нам не нужно назначать его вообще. Это хорошо работает, если мы получаем несколько пользовательских данных.

0 голосов
/ 05 февраля 2020

Один из вариантов:

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)
...