在F#中为C#对象初始值设定项创建一个LINQ表达式



我使用的是一个.NET框架,该框架允许在从C#调用时传递对象初始值设定项LINQ表达式:

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

框架使用参数中的表达式来检测哪些字段应该更新。

是否有可能从F#构建相同的LINQ表达式?我正在尝试使用引号来模拟对象初始值设定项,但到目前为止没有任何成功。我试过以下例子:

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

它编译时没有错误,但我得到了以下运行时错误:

System.NotSupportedException:无法将以下F#报价转换为LINQ表达式树

Sequential(Sequentious(Value((,PropertySet(Some(returnVal(,数量,[Call(None,MakeDecimal,[值(3(,值(0(,值,值(false(、值(0uy(](,returnVal(

位于Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.failConvert(FSharpExpr-inp(中的D:\a.work\1\s\src\FSharp\FSharp.Core\Linq.fs:line 666

这构造了一个等价的表达式:

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
|]),
[||])

最新更新