Как вызвать функцию или свойство в поставщике запросов LINQ (ExpressionVisitor) - PullRequest
0 голосов
/ 27 апреля 2018

Я создаю поставщика LINQ. И запрос может выглядеть так:

customers.Where( (f) => f.Date < DateTime.Now )

В моем поставщике запросов я выполняю ExpressionVisitor, который читает запрос и создает запросы MSSQL. Но я не могу узнать, как вызывать свойство DateTime.Now при посещении ExpressionTree.

При анализе дерева выражений я получаю преобразование выражений (Datetime.Now). Я хочу как-то назвать это свойство. Поэтому позже я могу добавить его к сгенерированному SQL-запросу. Выше у меня был запрос в синтаксисе C #, хотя я кодирую в VB.NET. Код как ниже:

 Protected Overrides Function VisitBinary(expr As BinaryExpression) As Expression
    expr = ETH.ConvertVBStringCompare(expr)

    If (expr.Right.NodeType = ExpressionType.Convert) Then
        Dim a = ETH.CallIt(expr)
    End If

Что происходит, когда я Expression.Right.NodeType имеет значение ExpresionType.Convert Я перехожу во вспомогательный класс:

Friend Shared Function CallIt(ByVal exp As BinaryExpression) As BinaryExpression

    If exp.Left.NodeType = ExpressionType.MemberAccess Then
        Dim compare = CType(exp.Left, MemberExpression)
        Dim compare1 = CType(exp.Right, UnaryExpression)

Когда я проверяю BinaryExpression, я вижу f.Date на левой стороне. И если я конвертирую exp.Right в Unary, я могу видеть его как Convert (DateTime.Now). Мне нужно как-то вызвать свойство DateTime.Now, чтобы я мог добавить его позже в запросе SQL. Как это:

select * from customers where Date < "2018-05..."

Я просто не могу понять, как вызвать свойство: (

UPDATE: Итак, я обнаружил, что в статье msdn для создания поставщика LINQ есть пример вспомогательного класса, частичного оценщика, который выполняет эту работу за вас. Он проходит через дерево выражений и оценивает вызовы функций и т. Д. Поэтому сейчас я использую этот класс в своем проекте. Это проще и возвращает дерево выражений, когда все готово.

1 Ответ

0 голосов
/ 27 апреля 2018

Вот вспомогательный метод расширения для оценки Expression s для получения их значения - вы должны указать тип возвращаемого значения, так как Expression не имеет его.

public static T Evaluate<T>(this Expression e) {
    //A little optimization for constant expressions
    if (e.NodeType == ExpressionType.Constant)
        return (T)((ConstantExpression)e).Value;
    else
        return (T)Expression.Lambda(e).Compile().DynamicInvoke();
}
...