1

Expr<int>以下のコードを使用して、一致する正しいパターンを見つけて実行しようとします。

open System.Linq

open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Quotations.Patterns

let runSelectQuery (q:Expr<IQueryable<'T>>) = 
    match q with
    | Application(Lambda(builder, Call(Some builder2, miRun, [Quote body])), queryObj) ->
        query.Run(Expr.Cast<Microsoft.FSharp.Linq.QuerySource<'T, IQueryable>>(body))
    | _ -> failwith "Cannot run this query %s" (q.ToString())

let runCountQuery (q:Expr<int>) = 
    match q with
    | Application(Lambda(builder, Call(None, miRun, [builder2, Quote body])), queryObj) ->
        query.Run(Expr.Cast<int>(body))
    | _ -> failwith "Cannot run this query %s" (q.ToString())

let countQuery source filter =
    let filter = match filter with | Some filter -> filter | _ -> <@ fun _ -> true @>
    <@ query { for item in source do
               where ((%filter) item)
               count } @>

runSelectQuery はExpr<IQueryable<'T>>パターンに正しく一致します。ただし、ジェネリック カウント クエリに一致する正しいパターンが見つかりませんExpr<int>

countQuery の署名から派生したコードのパターンから、次のことがわかります。

この式は Expr 型を持つことが期待されていましたが、ここでは 'a * 'b 型になっています

4

1 に答える 1

3

それを見つけた!ばかげて、私は最初にコンマ区切りパターンを使用して配列パターンを一致させようとしました (C# のリスト区切り文字と同様)。これは明らかに F# では機能せず、リストではなくタプルであり、したがって Rex ではありませんでした。

int の結果または任意の 'T の結果と照合するには:

let runQueryToQueryable (q:Expr<IQueryable<'T>>) = 
    match q with
    | Application(Lambda(builder, Call(Some builder2, miRun, [Quote body])), queryObj) ->
        query.Run(Expr.Cast<Microsoft.FSharp.Linq.QuerySource<'T, IQueryable>>(body))
    | _ -> failwith "Cannot run this query %s" (q.ToString())

let runQueryToType (q:Expr<'T>) = 
    match q with
    | Application(Lambda(builder, Call(None, miRun, [builder2; Quote body])), queryObj) ->
           query.Run(Expr.Cast<'T>(body))
    | _ -> failwith "Cannot run this query %s" (q.ToString())

魅力のように機能します。

于 2013-06-17T21:50:52.637 に答える