简体   繁体   English

在 F# 中为 C# ZA8CFDE6331BD59EB2AC96F8911C4B666 创建一个 LINQ 表达式

[英]Create a LINQ expression in F# for C# object initializer

I am using a .NET framework which allows to pass an object initializer LINQ expression when called from C#:我正在使用 .NET 框架,当从 ZD7EFA19FBE722372FD5ADB6027 调用时,该框架允许传递 object 初始化程序 LINQ 表达式

db.UpdateAdd( () => new InvoiceAccount { Quantity = 3 } );

The framework uses the expression from the argument to detect which fields should be updated.框架使用参数中的表达式来检测应该更新哪些字段。

Is there a possibility to construct same LINQ expression from F#?是否有可能从 F# 构造相同的 LINQ 表达式? I am trying to use quotations to simulate the object initializer, but so far without any success.我正在尝试使用引号来模拟 object 初始化程序,但到目前为止没有任何成功。 I've tried for example following:我尝试过以下示例:

let expr = 
        <@ fun () -> InvoiceAccount(Quantity = 3M) @>
        |> LeafExpressionConverter.QuotationToExpression 
        |> unbox<Expression<Func<InvoiceAccount>>>

db.UpdateAdd<InvoiceAccount>( expr )

which compiles without errors, but I get the following runtime error:编译时没有错误,但出现以下运行时错误:

System.NotSupportedException: Could not convert the following F# Quotation to a LINQ Expression Tree System.NotSupportedException:无法将以下 F# 报价转换为 LINQ 表达式树

Sequential (Sequential (Value (), PropertySet (Some (returnVal), Quantity, [Call (None, MakeDecimal, [Value (3), Value (0), Value (0), Value (false), Value (0uy)])])), returnVal) Sequential (Sequential (Value (), PropertySet (Some (returnVal)), Quantity, [Call (None, MakeDecimal, [Value (3), Value (0), Value (0), Value (false), Value (0uy)] )])), returnVal)

at Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.failConvert(FSharpExpr inp) in D:\a_work\1\s\src\fsharp\FSharp.Core\Linq.fs:line 666在 Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.failConvert(FSharpExpr inp) 在 D:\a_work\1\s\src\fsharp\FSharp.Core\Linq.fs:line 666

This constructs an equivalent expression:这构造了一个等价的表达式:

let invoiceAccountCtor = typedefof<InvoiceAccount>.GetConstructor([||])
let quantityProp = typedefof<InvoiceAccount>.GetMember(nameof Unchecked.defaultof<InvoiceAccount>.Quantity).Single()
let expr =
    Expression.Lambda(
        Expression.MemberInit(
            Expression.New(invoiceAccountCtor),
            [|
                Expression.Bind(quantityProp, Expression.Constant(3)) :> MemberBinding
            |]),
        [||])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM