F # - реконструировать дерево выражений - PullRequest
0 голосов
/ 25 апреля 2011

Хорошо ... этот вопрос более или менее связан с вопросом, который я задавал ранее сегодня ( F # - "Недопустимое выражение свойства" ), на который @Tomas Petricek отвечает идеально - как бы это ни казалосьмой недостаток знаний и DLR требует от меня еще раз попросить (довольно долго пытался что-то перепутать без удачи).

У меня есть эта функция (украдено из примера, который Томас далв предыдущем потоке):

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> to ICollection<'b> сделать так, чтобы выражение в конце было похоже на: 'a -> ICollection<'b>

Ответы [ 2 ]

3 голосов
/ 25 апреля 2011

Что ж, если вы уже разложили цитату, то, возможно, вы сможете самостоятельно создать требуемое дерево выражений без ToLinqExpression из PowerPack?

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 голос
/ 26 апреля 2011

Это не сработает.

Вы хотите построить цитату типа Entity -> ICollection<Something>, и у вас есть цитата типа Entity -> seq<Something>.Однако структура сущности поддерживает только простые лямбда-функции, которые получают некоторое свойство (например, x => x.SomeProperty).

Если у вашего Entity есть только свойство Foo типа seq<Something>, то вы не сможете построить предложение с требуемой структурой (лямбда, которая просто получает свойство) и с требуемойtype (Entity -> ICollection<Something>), поскольку тип свойства не совпадает!

То, что я предлагал ранее, - это изменить сущность, чтобы она также имела свойство FooInternal правильного типа (ICollection<Something>),Тогда вы могли бы построить цитату x => x.FooInternal, которая бы хорошо работала с платформой сущностей.

Возможно, вы могли бы дать более подробную информацию о том, чего вы на самом деле пытаетесь достичь?Мы можем попытаться помочь с техническими деталями, но, возможно, вам придется немного изменить свой дизайн (чтобы фактически работать с типом ICollection в соответствии с требованиями EF).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...