2012-04-15 15 views
4

FLINQを使用しようとしましたが、F#3.0ベータ版では古くなっています。F#3.0の動的SQLクエリ?

誰かがF#で動的SQLクエリを作成する方法について私にいくつかのポインタを教えてもらえますか?

答えて

5

F#3.0では、クエリは自動的に引用されるため、クエリの合成を可能にする引用スプライシング(<@ foo %bar @>構文)は使用できません。 、この道を

// Initial query that simply selects products 
let q1 = 
    query { for p in ctx.Products do 
      select p } 

// Create a new query that specifies only expensive products 
let q2 = 
    query { for p in q1 do 
      where (p.UnitPrice.Value > 100.0M) } 

:あなたはスプライシングを使用してクエリを合成して書くことができるものの大部分は、まだ前のソースから新しいクエリを作成し、すなわちフィルタリングを追加することによって、「通常のLINQの道」で行うことができます動的に条件を追加し、投影を動的に指定し(selectを使用)、他のいくつかのクエリ合成を行うことができます。ただし、明示的な引用と同様にクエリを構成する際の柔軟性は十分にありません。私はこれがF#3.0がC#に存在するものに似たより簡単な構文を支払わなければならないという価格だと思います。

query.Select(など)演算子を使用して明示的にクエリを書き込むことができるはずです。これは明示的な引用を使用して記述されるため、スプライシングを使用できるはずです。しかし、私は翻訳の仕組みを正確には知らないので、実際のサンプルを与えることはできません。このような何か作業をする必要があります(ただし、構文は非常に醜いですので、単に文字列や他のいくつかの技術を使用する方が良いでしょう):それは可能かもしれないので、IQueryableに基づいているF#3.0で

<@ query.Select(Linq.QuerySource<_, _>(ctx.Products), fun prod -> 
    // You could use splicing here, for example, if 'projection' is 
    // a quotation that specifies the projection, you could write: 
    // %projection 
    prod.ProductName) @> 
|> query.Run 

クエリをthe one that I implemented for C#と同じトリックを使用します。しかし、私はいくつかの詳細が異なると思うので、私はそれがすぐに動作するとは思わないでしょう。そのアイデアの最良の実装はLINQKitですが、私はF#で直接動作しないと思います。

一般的に、うまくいくのは最初の例だと思います。複数のクエリを作成してクエリに追加のクエリ演算子を適用するだけです。

11

私たちは最近、F#3.0以上でより柔軟なクエリ式の構成をサポートするためのライブラリFSharpComposableQueryを開発しました。これは、標準のクエリービルダーに負担をかけるドロップイン置換として意図されています。次のように

トーマスの例を変更することができます。

open FSharpComposableQuery 

// Initial query that simply selects products 
let q1 = 
    <@ query { for p in ctx.Products do 
      select p } @> 

// Create a new query that specifies only expensive products 
let q2 = 
    query { for p in %q1 do 
      where (p.UnitPrice.Value > 100.0M) } 

これは単に、クエリ式を引用し、2番目のクエリにそれをスプライス。しかし、これは式(トーマスの元のコードのように)する可能性があります

query { for p in (query { for p in ctx.Products do 
          select p }) do 
     where (p.UnitPrice.Value > 100.0M) } 

q2が(等価)と評価されたため、デフォルトQueryBuilderは、単一のクエリに変身することができないかもしれないことを引用されたクエリ式になりSQL選択クエリに変わります

query { for p in ctx.Products do 
     where (p.UnitPrice.Value > 100.0M) } 

:私たちが本当に欲しいことのようなものであるのに対し、メモリへの製品のすべてをロードし、メモリ内の選択をすることによって評価されます。 FSharpComposableQueryは、QueryBuilderを無効にして、この変換を実行します。したがって、クエリはより自由に引用や反注釈を使用して構成できます。

プロジェクトのホームページはこちらです:http://fsprojects.github.io/FSharp.Linq.ComposableQuery/

と私はちょうど動的照会については、別の(古い)疑問に提供答えでいくつかのより多くの議論があります:How do you compose query expressions in F#?

コメントや質問(特に何か場合は、休憩や仕事がすべきだと思うことはありません)は大歓迎です。

[編集:プロジェクトページへのリンクを更新しました。これは "Experimental"という単語を削除するように変更されました]