Linq Query для получения DataContext Entities на основе ILookup
Если у меня есть IEnumerable<int> Values
Я могу написать запрос Linq to Entities, например, так:
DataContext.Answers.Where(a => a.Organization == CurrentUser.Organization ||
Values.Contains(a.QuestionId))
(Values.Contains(a.QuestionId))
часть - то, что касается моего вопроса.
Если Values
были реализованы вместо этого как: ILookup<string, IEnumerable<int>>Values
Как я мог переписать запрос, чтобы получить Answers
где Values
содержит ключ (a.Organization
) и IEnumerable
значения для этого ключа содержат a.QuestionId
?
1 ответ
Сначала вам нужно сгладить ILookup<string, IEnumerable<int>>
в IEnumerable
некоторого элемента, который имеет как организацию, так и идентификатор вопроса. Вам нужно получить все группы в поиске, получить все коллекции идентификаторов из группы, а затем получить все идентификаторы в этой коллекции и преобразовать каждую из них в объект, содержащий как этот идентификатор, так и ключ группы. Вы можете использовать Contains
в этой коллекции, чтобы увидеть, находятся ли организация ответа и идентификатор вопроса в этой коллекции пар. Делая это, вы позволяете переводить коллекцию в предложение IN в SQL. Конечно, если поиск особенно велик, тогда это будет проблемой; если он маленький, его не будет.
Вы бы сделали это так:
var flattenedValues = (from grouping in Values
from ids in grouping
from id in ids
select new
{
Organization = grouping.Key,
QuestionId = id,
})
.ToList();
DataContext.Answers.Where(a => a.Organization == CurrentUser.Organization ||
flattenedValues.Contains(new
{
Organization = a.Organization,
QuestionId = a.QuestionId,
}));
Если поиск особенно велик, у вас может не быть другого выбора, кроме как вытащить все данные из таблицы в память и отфильтровать их, просматривая поиск на стороне приложения, или загрузить данные в этом поиске во временную таблицу в список.