Ste*_*ing 4 f# c#-to-f# windows-runtime f#-3.0
我正在尝试在WinRT 8.1应用程序中的F#项目中使用Lex.Db数据库.
我正在关注C#的本教程.我成功地将一个对Lex.Db的引用添加到了一个F#项目中,并且教程中的简单调用转换为f#并编译(例如let db = new DbInstance("demo")).
问题是这个C#代码:
db.Map<Contact>().Key(i => i.Id)
Run Code Online (Sandbox Code Playgroud)
- 编辑 -
为了避免其他人进一步阅读,在F#3.0中,这几乎不是问题.请参阅下面的kvb评论.解决方案是:
db.Map<Contact>().Key(fun i => i.Id)
- /编辑---
该Key函数需要一个Expression<Func<Contact,'a>>,我无法在F#中构建它.
在如何将LinQ表达式从F#传递到C#代码中出现了一个非常类似的问题.推荐的解决方案是使用LeafExpressionConverter.QuotationToLambdaExpression.
我试过这个如下:
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
Run Code Online (Sandbox Code Playgroud)
这会产生编译器错误idExpr:
类型不匹配.期待Expression<Func<Contact,'a>>但是给了一个Expression<(Contact -> int)>.类型'Func<Contact,'a>'与类型不匹配'Contact -> int'.
这个问题:来自F#func的Expression <Func <T,bool >>似乎直接解决了这个问题,但该解决方案使用的是Microsoft.FSharp.Linq.QuotationEvaluation,我在F#3.0中找不到WinRT.
我怎么<@ fun (c : Contact) -> c.Id @>变成一个Expression<Func<Contact,'a>>?
Microsoft.FSharp.Linq.QuotationEvaluation在PowerPack中,但从v3.0开始,它提供的功能在Core via中可用LeafExpressionConverter.您可以使用您链接的问题中的代码,但将其更改为LeafExpressionConverter用于翻译部分.
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)
Run Code Online (Sandbox Code Playgroud)