Pull to refresh

Comments 5

Насколько я понял, проблема состояла в том, что вы вызывая код:
source.Where(item => values.Contains(item.Property))

в полученное выражение подставляется замыкание на values.
Для решения этой простой задачи вы наворотили какое-то странное решение, где вы начисто убили строгую типизацию, в чем есть смысл LINQ (intergrated!).
Тут много достаточно хороших способов решения.
Например, можно транслировать дерево выражения, заменив замыкание values на составляющие Or.
А еще лучше сделать отдельную Where Where(this IQueryable<T> source, Expression<Func<T,TResult>> selector, IEnumerable<TResult> values). Там бы и конструировался ваш запрос с помощью Or.
Проблема состояла в том, что Microsoft.WindowsAzure.StorageClient.TableServiceContext не поддерживает Contains в принципе. Поэтому приходится конструировать его через Or.
И вот та самая строгая типизация LINQ нисколько не помогает в решении. Конечно оно может быть и не оптимальным, но оно работает и решает наши задачи просто блестяще.
А я все же сторонник принципа «хорошее решение — это то, которое работает».
Если вы сможете предложить что-то лучшее — то с удовольствием посмотрю на ваше решение.
Так я же вам и написал более элегантное решение. Вот такая сигнатура:
public static IQueryable<T> WhereContains(this IQueryable<T> source, IEnumerable<TResult> values, Expression<Func<T, TResult>> selector)

Использовать очень просто:
source.WhereContains(new [] { value1, value2, value3 }, obj => obj.FieldOrProperty);

Реализовать такую функцию можно без проблем, использую ExpressionVisitor.
Такое выражение развернется в:
source.Where(obj => obj.FieldOrProperty == value1 || obj.FieldOrProperty == value2 || obj.FieldOrProperty == value3);

То же самое, что делает ваша функция, только строготипизировано. Использовать from… where… select конечно нельзя.
А есть и более сложное, но элегантное решение. Можно подменить QueryProvider и там при конструировании .Where анализировать деревья выражений на наличие замыканий и также переписывать выражения.
Спасибо, попробую немного переписать. Возможно в финальной версии библиотеки появится более элегантное решение :)
Sign up to leave a comment.

Articles