2011-02-10 7 views
3

私はF#とLinqをUDFのために使用しようとしていて、SQLサーバにprocsを保存しようとしているプロジェクトに取り組んでいます。 その一部は、すべての有効なクエリ、並べ替え基準、およびクエリの結果をスコアリングする手段を静的に定義することでした。linqクエリで多くの引用を構成しています

これまではかなり成功しましたが、私はsortBy式を構成することに深刻な困難を抱いています。

はここでこれはとても

let execQuery = fun (predicates,sorts,scorer) -> 
    <@ seq { for prod in (%dc).Products do 
       if (%predicates) prod then yield prod } 
     |> (%sorts) 
     |> (%scorer) @> 

これらの基本的なアウトラインを使用するようにクエリエグゼキュータの後半で使用されてしまうの基本的な考え方

let sorter = 
    let exprMap:Map<string,Quotations.Expr<seq<Product> -> seq<Product>>> = 
    Map.ofList 
    ["ProductName",<@ Seq.sortBy (fun prod -> prod.Name) @> ] 
    // .. more entries .. 
    let sortBuilder sortkeys = 
     Array.foldBack 
     (fun criteria acc -> <@ %(exprMap.[criteria]) >> (%acc) @>) 
     sortkeys 
     <@ Seq.map id @> 

だ、すべてがいる限り、私は(使用しないように動作します%ソート)。私がそれを渡すたびに、Linqの翻訳者にF#で認識されません。私はコンビネータを使用する際にさまざまな試みを試みましたが、私は何かが欠けているという感覚を持っています。

<@ Seq.sortBy (fun prod -> prod.Name) |> Seq.sortBy (fun prod -> prod.Style) @> 

これは、次のようにソーター機能をスタブアウトすると正常に動作します。しかし、このようにコンビネータを使用して:

let (|>*) = fun f g -> <@ fun c -> ((%f) c) |> (%g) @> 

にはない..

任意のアイデア?

答えて

1

残念ながら、私はこの質問に対する良い答えはありません。

F#LINQトランスレータは現在、クエリの構造に非常に敏感です。コンポジションを使うと、手書きで書くと同じ引用符を得ることができるはずです。手書きで書いたのと全く同じものを生成する必要があります。

let (|>*) f g = fun c -> <@ (%c) |> (%f) |> (%g) @> 

<@ seq { for prod in (%dc).Products do 
      if (%predicates) prod then yield prod } @> |> 
(<@ Seq.sortBy (fun prod -> prod.Name) @> |>* 
    <@ Seq.sortBy (fun prod -> prod.Style) @>) 

問題:

たとえば、あなたのソーターで、あなたのような何かを(私はそれを試していないが、私はこの作品いつものコードと全く同じ引用を作るべきだと思います)必要があるかもしれません引用符にラムダ関数を含めると、F#トランスレータはそれらを処理する必要があります(おそらくLINQ to SQLトランスレータが失敗するため)おそらくそれらを部分的に評価することによって対処する必要があります。これにはいくつかのトリッキーなケースがあります...

しかし、F#チームは最近このエリアでいくつかの改善を行っています。最高のことは、簡単な復習ケースを見つけてfsbugsマイクロソフトドットcomに送信することです。 PowerPackのリリースはそれほど「センシティブ」ではありませんので、テストをして助けてもらえれば、最近の変更でソースコードを入手できるかもしれません。

関連する問題