好吧......这个问题或多或少与我今天早些时候提出的问题有关(F# - "Not a valid property expression"),@ Tomas Petricek完全回答 - 但是看来我缺乏知识和DLR,需要我再问一次(一直试着将一些东西搞砸而没有运气)。
我正在使用此功能(从前一个帖子中Tomas给出的示例中窃取):
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!"
如何使用Expr.Lambda
和Expr.PropGet
重建表达式树? - 我需要改为seq<'b>
到ICollection<'b>
,以便最后的表达式如下:'a -> ICollection<'b>
答案 0 :(得分:3)
好吧,如果您已经分解了引用,那么也许您可以自己创建所需的表达式树,而不需要PowerPack中的ToLinqExpression
?
type A =
member this.Values : int[] = failwith ""
open Microsoft.FSharp.Quotations
type F<'T, 'R> = System.Func<'T, 'R>
type E = System.Linq.Expressions.Expression
type IC<'T> = System.Collections.Generic.ICollection<'T>
let toLinqPropGet (e : Expr<'T -> #seq<'R>>) =
match e with
| Patterns.Lambda(_, Patterns.PropertyGet(Some _, pi, []))
when typeof<IC<'R>>.IsAssignableFrom(pi.PropertyType) ->
let p = E.Parameter(typeof<'T>)
let propGet = E.Property(p :> E, pi)
E.Lambda<F<'T, IC<'R>>>(propGet, p) :> E
| _ -> failwith "PropGet expected"
let r = toLinqPropGet <@ fun (x : A) -> x.Values @>
printfn "%A" r
答案 1 :(得分:1)
这不起作用。
您希望构建类型为Entity -> ICollection<Something>
的引号,并且引用类型为Entity -> seq<Something>
的引号。但是,实体框架仅支持获取某些属性的简单lambda函数(例如x => x.SomeProperty
)。
如果您的Entity
只有Foo
类型的属性seq<Something>
,则无法构建具有所需结构的引用(仅获取属性的lambda)和所需类型(Entity -> ICollection<Something>
),因为属性的类型不匹配!
我之前建议的是将实体更改为具有正确类型(FooInternal
)的属性ICollection<Something>
。然后你可以构建一个引用x => x.FooInternal
,它可以与实体框架一起使用。
也许您可以提供有关您实际尝试实现的内容的更多详细信息?我们可以尝试帮助提供技术细节,但似乎您可能需要稍微调整一下您的设计(以实际使用EF所要求的ICollection
类型)。