Comments 5
Насколько я понял, проблема состояла в том, что вы вызывая код:
в полученное выражение подставляется замыкание на values.
Для решения этой простой задачи вы наворотили какое-то странное решение, где вы начисто убили строгую типизацию, в чем есть смысл LINQ (intergrated!).
Тут много достаточно хороших способов решения.
Например, можно транслировать дерево выражения, заменив замыкание values на составляющие Or.
А еще лучше сделать отдельную Where
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 нисколько не помогает в решении. Конечно оно может быть и не оптимальным, но оно работает и решает наши задачи просто блестяще.
А я все же сторонник принципа «хорошее решение — это то, которое работает».
Если вы сможете предложить что-то лучшее — то с удовольствием посмотрю на ваше решение.
И вот та самая строгая типизация LINQ нисколько не помогает в решении. Конечно оно может быть и не оптимальным, но оно работает и решает наши задачи просто блестяще.
А я все же сторонник принципа «хорошее решение — это то, которое работает».
Если вы сможете предложить что-то лучшее — то с удовольствием посмотрю на ваше решение.
Так я же вам и написал более элегантное решение. Вот такая сигнатура:
Использовать очень просто:
Реализовать такую функцию можно без проблем, использую ExpressionVisitor.
Такое выражение развернется в:
То же самое, что делает ваша функция, только строготипизировано. Использовать from… where… select конечно нельзя.
А есть и более сложное, но элегантное решение. Можно подменить QueryProvider и там при конструировании .Where анализировать деревья выражений на наличие замыканий и также переписывать выражения.
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.
Расширения LINQ для Azure Table Storage, реализующие Or и Contains