F#-;不是有效的属性表达式";

F#-;不是有效的属性表达式";,f#,F#,我有一个以Expr为参数的方法: member x.HasSeq (expr:Expr<'a -> 'b seq>) = let casted = <@ fun z -> (%expr) z :?> ICollection<'b> @> ManyNavPropertyInfo(cfg.HasMany <| toLinq casted) 我以前使用过toLinq函数,没有任何问题-我认为这是因为我将b seq转换为IC

我有一个以Expr为参数的方法:

member x.HasSeq (expr:Expr<'a -> 'b seq>) = 
    let casted = <@ fun z -> (%expr) z :?> ICollection<'b> @>
    ManyNavPropertyInfo(cfg.HasMany <| toLinq casted)

我以前使用过
toLinq
函数,没有任何问题-我认为这是因为我将
b seq
转换为
ICollection您的推理是正确的-问题是
HasMany
方法只识别特定的C#表达式树,而F#code生成的表达式树是不同的


我的猜测是,EF只处理表达式树是对正确类型的属性的简单访问的情况——在C#语法中,类似于:
x=>x.Foo
(无任何强制转换等)。我认为最好的选择是修改您的代码,使其也包含一个函数
'a->ICollection seq您的上一种方法看起来很有趣,但是我不确定如何将
Expr.Lambda
Expr.PropGet
混合在一起,以构建表达式树。你介意做个演示吗?如果我让函数期望一个
'a->ICollection
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) 
let hasSeq (e:Expr<'a -> seq<'b>>) =
  match e with
  | Patterns.Lambda(v, Patterns.PropertyGet(Some instance, propInfo, [])) ->
      printfn "Get property %s of %A" propInfo.Name instance
      // TODO: Use 'Expr.Lambda' & 'Expr.PropGet' to construct
      // an expression tree in the expected format
  | _ -> failwith "Not a lambda!"