I am trying use the Lex.Db database in an F# project in a WinRT 8.1 app.
I am following this tutorial for C#. I've successfuly added a reference to Lex.Db to an F# project and the simple calls in the tutorial translate to f# and compile (eg. let db = new DbInstance("demo")
).
The problem is this C# code:
db.Map<Contact>().Key(i => i.Id)
-- Edit --
To save others from reading further, in F# 3.0 this is almost a non-problem. See kvb's comment below. The solution is:
db.Map<Contact>().Key(fun i => i.Id)
-- /Edit ---
The Key
function expects an Expression<Func<Contact,'a>>
and I am unable to build this in F#.
A very similar question appears in How to pass LinQ Expressions from F# to C# code. The recommended solution is to use LeafExpressionConverter.QuotationToLambdaExpression
.
I have tried this as follows:
type Contact() =
member val Id = 0 with get, set
member val FirstName = "" with get, set
let db = new DbInstance("Demo")
let idExpr = LeafExpressionConverter.QuotationToLambdaExpression
<@ fun (c : Contact) -> c.Id @>
db.Map<Contact>().Key(idExpr) |> ignore // <- Error
This produces a compiler error on idExpr
:
Type mismatch. Expecting a Expression<Func<Contact,'a>>
but given a Expression<(Contact -> int)>
. The type 'Func<Contact,'a>'
does not match the type 'Contact -> int'
.
This question: Expression<Func<T, bool>> from a F# func seems to address the problem directly, but the solution uses Microsoft.FSharp.Linq.QuotationEvaluation, which I can't find in F# 3.0 for WinRT.
How do I turn <@ fun (c : Contact) -> c.Id @>
into an Expression<Func<Contact,'a>>
?
Microsoft.FSharp.Linq.QuotationEvaluation
is in PowerPack, but as of v3.0 the functionality it provides is available in Core via LeafExpressionConverter
. You can use the code in the question you linked, but change it to use LeafExpressionConverter
for the translation part.
open System
open System.Linq.Expressions
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Linq.RuntimeHelpers
let toLinq (expr : Expr<'a -> 'b>) =
let linq = LeafExpressionConverter.QuotationToExpression expr
let call = linq :?> MethodCallExpression
let lambda = call.Arguments.[0] :?> LambdaExpression
Expression.Lambda<Func<'a, 'b>>(lambda.Body, lambda.Parameters)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With