给出:
open System
open System.Linq.Expressions
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Linq.RuntimeHelpers
open FizzWare.NBuilder
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)
let inline with'<'a,'b> (f:Expr<'a->'b>) (value:'b) (operable:IOperable<'a>) =
let f = toLinq f
operable.With(f,value)
let size = 20
let builderList =
Builder<dbEncounter.ServiceTypes.Patients>.CreateListOfSize(size).All()
|> with' <@ fun x -> x.PatientID @> 0
|> with' <@ fun x -> x.ForeignEHRID @> (Nullable 0)
|> with' <@ fun x -> x.PatientInfoID @> (Nullable 0)
|> (fun b -> b.With(fun x-> x.PatientGUID <- Nullable (Guid.NewGuid()); x.PatientGUID ))
|> withf (fun x-> x.PatientGUID <- Nullable (Guid.NewGuid()); x.PatientGUID) // this line doesn't compile as a replacement for the previous line
我尝试撰写withf
:
let inline withf<'a,'b> (f:Func<'a,_>) (operable:IOperable<'a>) =
operable.With(f)
尝试使用withf
替换其他选项的错误是
答案 0 :(得分:1)
感谢@kvb对另一个问题的其他答案
,找到了答案Interop between F# and C# lambdas
我只需要像这样调用Func
构造函数:
let inline withf<'a,'b> (f:'a->'b) (operable:IOperable<'a>) =
operable.With(Func<'a,'b>(f))
现在这样可行:
let makePatients size =
let builderList =
Builder<dbEncounter.ServiceTypes.Patients>.CreateListOfSize(size).All()
|> with' <@ fun x -> x.PatientID @> 0
|> with' <@ fun x -> x.ForeignEHRID @> (Nullable 0)
|> with' <@ fun x -> x.PatientInfoID @> (Nullable 0)
//|> (fun b -> b.With(fun x-> x.PatientGUID <- Nullable (Guid.NewGuid()); x.PatientGUID ))
|> withf (fun x-> x.PatientGUID <- Nullable (Guid.NewGuid()); x.PatientGUID)