Question

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>>?

Was it helpful?

Solution

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) 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top