2012-04-30 12 views
3

最近紹介されたF#3.0のクエリの理解構文を使用してBill of Materialsの種類のクエリを定義しようとしています。メモリ内のコレクションについては、yield! seqの包括を使用してこれらの種類のクエリを定義することは可能ですが、リモートIQueryableソースを対象とするクエリの包摂に変換することはありませんでした。私は、再帰的なパターンからCommon Table Expressionsを認識するようにプロバイダを「訓練する」ことが難しいと思います。再帰的クエリの補完(F#3.0)

アイデア?

+0

私は嫌なことはしませんが、ここに再び投稿する予定がある場合は、次をご覧ください:http://stackoverflow.com/faq#signatures署名やタグラインは必要ありません実際、それは落胆しているのです。 –

答えて

5

残念ながら、F#3.0の現在のクエリ構文サポートが再帰クエリを処理できるとは思いません。主な問題は、F#3.0が主にC#用に設計された標準IQueryable実装に依存しているため、再帰構造を期待していないことです。

これをサポートすることは非常に難しいと思います。あなたは、SQLトランスレータ(難しい)に独自のF#引用を実装することもできますし、再帰を含むF#引用(クエリ)を取り、LINQからSQLへの変換ができる何かに再帰を変換するプリプロセッサを実装することもできます対処する(しかし、これはおそらく難しい)。

一般的に、このアプローチは、独自のクエリービルダーを定義するには、次のようになります。

open System.IO 
open Microsoft.FSharp.Quotations 

type MyQueryBuilder() = 
    member x.For(a, body) = Seq.collect body a 
    member x.Quote(e) = e 
    member x.YieldFrom(s) = s 
    member x.Run(e:Expr<'T>) : 'T = failwithf "%A" e 

// Example using the custom query builder 
// (fails, printing the quoted query) 
let mquery = MyQueryBuilder()  
let n = [1 .. 10] 

let rec nums a : seq<int> = 
    mquery { for b in n do 
      yield! nums b } 

Run方法では、クエリを表し見積を取得します。あらかじめ処理しておき、すべての呼び出しをMyQueryBuilderに置き換えて、標準のqueryオペレーションを呼び出し、再帰を別のものに置き換えることができます。その後、query.Run(標準IQueryableの実装を実行するために)を呼び出すことができます。

私が言ったように、これは実装するのが非常に難しいでしょうが、おそらく、あなたが簡単に対処できる特定の種類の再帰を持っているなら、オプションかもしれません。しかし、LINQ to SQLが標準パターンのCommon Table Expressionsを生成しない場合は、生成するようにトレーニングすることはできません。私が知る限り、トランスレータは実際には拡張可能ではありません。