将F#引用转换为LINQ表达式
我可以通过以下代码段将Expr 'b>
类型的引号转换为Linq表达式:
/// Converts a F# Expression to a LINQ Lambda let toLambda (exp:Expr) = let linq = exp.ToLinqExpression() :?> MethodCallExpression linq.Arguments.[0] :?> LambdaExpression /// Converts a Lambda quotation into a Linq Lamba Expression with 1 parameter let ToLinq (exp : Expr 'b>) = let lambda = toLambda exp Expression.Lambda<Func>(lambda.Body, lambda.Parameters)
现在我想将Expr 'c>
或甚至Expr 'b -> 'c>
类型的引用转换为Expression<Func>
类型的Linq Lambda表达式Expression<Func>
。
我怎样才能做到这一点?
此致,forki
我不确定这是否由F#PowerPack中提供的LINQ模块直接支持。 但是,您可以实现自己对F#库生成的LINQ表达式的后处理,将其转换为通常forms的C#lambda函数:
以下函数采用LINQ表达式,该表达式构造为单个参数的多个嵌套LambdaExpression
表达式(即F#转换器生成的结构),并返回最内层表达式的参数列表和主体:
let rec translateExpr (linq:Expression) = match linq with | :? MethodCallExpression as mc -> let le = mc.Arguments.[0] :?> LambdaExpression let args, body = translateExpr le.Body le.Parameters.[0] :: args, body | _ -> [], linq
现在你可以使用它来获取一个普通的Func
委托类型,如int -> int -> int -> int
如下所示:
let linq = (<@@ fun abc -> (a + b) * c @@>).ToLinqExpression() let args, body = translateExpr liq let f = Expression.Lambda> (body, args |> Array.ofSeq) f.Compile().Invoke(10, 11, 2)