2015-05-20 2 views
1

Я работаю над поставщиком LINQ, поэтому я внедряю IQueryable..NET LINQ IQueryable: что такое выражение?

Что является целью свойства Expression в этом интерфейсе? Обычно я возвращаю что-то вроде Expression.Constant(this) из моих реализаций, но понятия не имею, плохо ли это.

В Bizarrely documentation указано «Это позволяет разграничению между запросами LINQ и Entity SQL».

+0

Попробуйте посмотреть, что присутствует в EF или LINQ-to-SQL в этой собственности ... – xanatos

+1

Как я помню, 'Expression' собственности содержит выражение для текущего 'IQueryable', поскольку мы можем иметь цепочку из них, поэтому каждый' IQueryable' имеет свои собственные и ранее сгруппированные выражения. Но я могу ошибаться, поскольку я использую это давно. –

+0

@SergeyLitvinov Да, я знаю, что это один из возможных способов его использования, но насколько я знаю, нет необходимости в том, чтобы инфраструктура использовала его таким образом. Так ли это свойство для разработчиков, как им нравится? –

ответ

3

IQueryable.Expression элемент подается обратно в IQueryProvider всех различных Queryable.* "операторов" (.Where(), .Select(), .Join() ...), как:

public static IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate) { 
    if (source == null) 
     throw Error.ArgumentNull("source"); 
    if (predicate == null) 
     throw Error.ArgumentNull("predicate"); 
    return source.Provider.CreateQuery<TSource>( 
     Expression.Call(
      null, 
      ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)), 
      new Expression[] { source.Expression, Expression.Quote(predicate) } 
      )); 
} 

(взято из referencesource)

Обычно это должно быть целое выражение.

Очевидно, что никто не убьет вас, если вы передадите прямое обращение к вашему IQueryable классу через Expression.Constant(), но я думаю, что это не «кошер».

Точка ввода «реального» выражение в Expression (как это делается в Enumerable.AsQueryable(), на EF и LINQ-to-SQL, просто назвать три IQueryable провайдеров) является то, что другие внешние классы могут свободно анализировать и манипулировать Expression и кормить его обратно поставщику таким же образом, что Queryable.Where делает, таким образом

Expression expression = source.Expression; 
// here "expression" is manipulated 
return source.Provider.CreateQuery<SomeType>(expression); 

чтобы дать пример ... Есть некоторые «запрос закрепитель» s, что изменить запрос, как https://github.com/davidfowl/QueryInterceptor (общий модификатор запросов) или https://github.com/hazzik/DelegateDecompiler, что позволяет:

var employees = (from employee in db.Employees 
       where employee.FullName == "Test User" 
       select employee).Decompile().ToList(); 

где FullNameне отображается в БД, и это свойство, как:

class Employee 
{ 
    [Computed] 
    public string FullName 
    { 
     get { return FirstName + " " + LastName; } 
    } 

FirstName и LastName, отображенного в дБ). DelegateDecompiler принимает Expression от IQueryable, ищет свойства, которые имеют атрибут Computed, декомпилирует их и помещает декомпилированный код (преобразуется в дерево выражения) обратно в IQueryable.Expression (хотя использование IQueryable.Provider.CreateQuery())

Если у вас хотите сохранить дополнительные данные, вы можете поместить их в Provider: вы можете сгенерировать новый экземпляр класса IQueryProvider в методе CreateQuery. Это тоже подается обратно по Queryable.* операторов (поскольку CreateQuery<> является метод экземпляра source.Provider)

+0

Спасибо за подробный ответ. В качестве небольшого последующего вопроса, относительно условно использовать свойство Expression, чтобы пытаться модифицировать, дублировать или иным образом проверять запросы? Я никогда не видел этого на практике, и предполагал, что это очень неизвестная функция. –

+0

О, и моя реализация открывает другие свойства, которые позволяют проверять сконфигурированный запрос, поэтому выражение Expression.Constant (this) 'не так глупо, как могло показаться на первый взгляд. –

+0

@IanNewson Я бы сказал, что он редко встречается у программистов, необычных в библиотечных писателях. – xanatos

Смежные вопросы