EF Core 2, .NET CORE 2: как запросить один и тот же столбец для нескольких условий с помощью IQueryable ‹T›?

У меня есть таблица базы данных, подобная той, что на изображении ниже.

Таблица с 2 столбцами (UserId и значение)

Я передам UserId вместе с двумя строками. Например: userId: 1, key1: h1, key2: h2 для APi с аналогичной подписью.

Public List<T> CheckValuesForUser(string userId, string key1, string key2)

Мне нужно проверить, имеет ли конкретный userId 1 значения h1 и h2. Если у пользователя нет обоих ключей, запрос должен вернуть значение null.

Я пробовал следующие запросы,

  1. context.tableName.where(i=> i.value.Equals("h1") && i.value.Equals("h2")) - ничего не возвращает. Я предполагаю, что этот предикат выполняется для каждой строки.
  2. Context.tableName.Where(i=> new string[]{ Key1,Key2 }.Contains(i.Value)) - возвращает значение, даже если у пользователя нет значения для Key2. Мне нужно получить результат NULL, если у пользователя нет обоих ключей.
  3. var list1= Context.tableName.Where(i=> i.Value.Equals(key1)).toList(); var list2= Context.tableName.Where(i=> i.Value.Equals(Key2)).toList(); if(list1.Count > 0 && list2.Count > 0) list1.AddRange(list2);

Может ли кто-нибудь помочь мне найти лучшее решение? Я использую Asp.Net Core 2.2


person Anish    schedule 20.04.2020    source источник
comment
можешь попробовать Context.tableName.Where(i=> new string[]{ Key1,Key2 }.All(x=>x == i.Value))   -  person Mohammed Sajid    schedule 20.04.2020


Ответы (2)


Поскольку записи h1 и h2 являются отдельными записями, вам нужно будет проверить оба значения независимо.

// Group the records by the expected UserId
var groupedRecords = context
                     .TableName
                     .Where(t => t.UserId == userId)
                     .GroupBy(t => t.UserId);

// Ensure both the required records exist within the grouping
var hasRequiredRecords = groupedRecords.Any(i => i.Value.Equals("h1"))
                                        && Any(i => i.Value.Equals("h2"))

// Now that you know you have the required values, return them
return groupedRecords.Where(i => i.Value.Equals("h1") && i.Value.Equals("h2");

Последняя строка вернет только две записи со значениями h1 и h2 для предоставленного userId, представленного как один List<T>

person Matt Hensley    schedule 20.04.2020
comment
Это работает, но мне действительно нужны были обе записи. Так что я получаю их в 2 переменных и объединяю результат .. Когда я использую concat в IQueryable, я сталкиваюсь с исключением. - person Anish; 23.04.2020
comment
@Anish Я обновил свой ответ, чтобы вернуть предметы в ожидаемом вами формате. - person Matt Hensley; 23.04.2020

Вы можете попробовать этот код, чтобы получить то, что хотите:

string[] keys = new string[] { key1, key2 };
var result = (from m in context.UserInfo
              where m.UserId == userId && keys.Any(name => name.Equals(m.Value)) select m).ToList().Count < keys.Count() ? null : 
              (from m in context.UserInfo where m.UserId == userId && keys.Any(name => name.Equals(m.Value)) select m).ToList();

Когда условие не выполняется, результат принимается как нулевой, если он выполняется, в результат возвращается соответствующий набор данных.

person LouraQ    schedule 21.04.2020