我有这种方法,这需要Expr的作为参数:F# - “不是有效的属性表达”
member x.HasSeq (expr:Expr<'a -> 'b seq>) =
let casted = <@ fun z -> (%expr) z :?> ICollection<'b> @>
ManyNavPropertyInfo(cfg.HasMany <| toLinq casted)
我想是到'b seq
强制转换为ICollection<'b>
,这似乎为它工作应该,但是当它到达到哪里去给Expr的转换为LINQ线(需要这样做,因为cfg.HasMany
节选一System.Expression<Func<'a,ICollection<'b>>>
)它只是抛出一个异常说:
出现InvalidOperationException:
表达 'Z => UnboxGeneric(ToFSharpFunc(Z => z.Books).Invoke(Z))' 是不是一个有效 属性表达。表达式 应表示一个属性:C#:'t => t.MyProperty'VB.Net:'Function(t) t.MyProperty'。
我用expr的转换为LINQ的功能:前
let toLinq (exp : Expr<'a -> 'b>) =
let linq = exp.ToLinqExpression()
let call = linq :?> MethodCallExpression
let lambda = call.Arguments.[0] :?> LambdaExpression
Expression.Lambda<Func<'a, 'b>>(lambda.Body, lambda.Parameters)
我用toLinq
功能没有问题 - 我想这是因为我投b seq
到ICollection<'b>
这让在Expr
UnboxGeneric
和当通过Expr
到toLinq
它简直不知道该怎么处理UnboxGeneric
- 但当然这只是一个理论,我不知道该怎么做才能解决它。
最后一种方法看起来很有趣,但我不确定如何混合'Expr.Lambda'和'Expr.PropGet'来构建表达式树。你介意给出一个解释; =)? – ebb 2011-04-25 13:40:16
如果我让函数期望''a - > ICollection <'b>',那么当你调用函数时,你只需要抛出'seq <'b>',这会产生相同的错误。 – ebb 2011-04-25 13:45:36