Использование Any () внутри Where () в EF Core 3.1 - PullRequest
0 голосов
/ 06 апреля 2020
await this.dbContext
          .UserTeams
          .Where(ut =>
                   teamMembers.Any(tm => tm.UserId == ut.UserId 
                                         && ut.TeamId == tm.TeamId))
          .ToListAsync();

здесь teamMember - это простой список, содержащий сгруппированные UserIds и TeamIds. Это работает, если я использую Contains(), но UserId и TeamId - здесь составной ключ.

Это довольно простой запрос и не может быть переведен.

Ошибка:

System.InvalidOperationException: The LINQ expression 'DbSet<UserTeam>
     .Where(u => __teamMembers_0
         .Any(tm => u.TeamId == tm.TeamId && u.UserId == tm.UserId))' 
could not be translated. 
Either rewrite the query in a form that can
be translated, or switch to client evaluation explicitly by inserting
a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or
ToListAsync()

1 Ответ

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

Проблема в том, что EF не может переводить сложные объекты. EF может переводить только. NET объект памяти в SQL параметрах и использовать эти SQL параметры в запросе SQL.

Я вижу один вариант, который может работать. Поскольку вы ничего не делаете, например, c, кроме простого поиска объединенных значений, вы можете попытаться преобразовать комбинацию user-id / team-id в один параметр SQL. Например, строка со значением '-'. Я предполагаю, что ваши идентификаторы простые числа. Если они строковые, то может потребоваться другой символ-разделитель. Используйте это объединенное значение, чтобы найти любое совпадение в вашем источнике БД.

Код ниже не проверен и может не работать. Альтернативой является создание некоторого вида для создания значения комбинации на стороне базы данных.

    var memberIds = teamMembers.Select(tm => $"{tm.UserId}-{tm.TeamId}").ToArray();
    await this.dbContext
              .UserTeams
              .Where(ut => memberIds.Contains(
                               SqlFunctions.StringConvert((double?)tm.UserId) + "-" +
                               SqlFunctions.StringConvert((double?)tm.TeamId)
                           )
                    )
              .ToListAsync();
...