如何在 LINQ 查询提供程序 (ExpressionVisitor) 中调用函数或 属性
How to call a function or property in a LINQ Query Provider (ExpressionVisitor)
我正在创建 LINQ 提供程序。查询可能如下所示:
customers.Where( (f) => f.Date < DateTime.Now )
在我的查询提供程序中,我执行一个 ExpressionVisitor 来读取查询并创建 MSSQL 查询。但是当我访问 ExpressionTree 时,我找不到如何调用 DateTime.Now 属性。
解析表达式树时,我得到了表达式转换 (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 我进入一个助手 class:
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 转换为一元,我可以将其视为 Convert(DateTime.Now)。
我需要以某种方式调用 DateTime.Now 属性,以便稍后在 SQL 查询中附加它。
像这样:
select * from customers where Date < "2018-05..."
我只是不知道如何调用 属性 :(
更新:
好的,所以我发现用于创建 LINQ 提供程序的 msdn article 有一个帮助程序 Class 的示例,它是一个部分计算器,可以为您完成这项工作。它遍历表达式树并评估函数调用等。
所以我现在在我的项目中使用 class。它更容易,完成后 returns 表达式树。
这是一个辅助扩展方法,用于评估 Expression
s 以获得它们的值 - 您必须指定 return 类型,因为 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();
}
我正在创建 LINQ 提供程序。查询可能如下所示:
customers.Where( (f) => f.Date < DateTime.Now )
在我的查询提供程序中,我执行一个 ExpressionVisitor 来读取查询并创建 MSSQL 查询。但是当我访问 ExpressionTree 时,我找不到如何调用 DateTime.Now 属性。
解析表达式树时,我得到了表达式转换 (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 我进入一个助手 class:
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 转换为一元,我可以将其视为 Convert(DateTime.Now)。 我需要以某种方式调用 DateTime.Now 属性,以便稍后在 SQL 查询中附加它。 像这样:
select * from customers where Date < "2018-05..."
我只是不知道如何调用 属性 :(
更新: 好的,所以我发现用于创建 LINQ 提供程序的 msdn article 有一个帮助程序 Class 的示例,它是一个部分计算器,可以为您完成这项工作。它遍历表达式树并评估函数调用等。 所以我现在在我的项目中使用 class。它更容易,完成后 returns 表达式树。
这是一个辅助扩展方法,用于评估 Expression
s 以获得它们的值 - 您必须指定 return 类型,因为 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();
}