FLINQ を使用しようとしましたが、F# 3.0 ベータ版では時代遅れです。
F# で動的 SQL クエリを作成する方法を教えてもらえますか?
私たちは最近FSharpComposableQuery
、F# 3.0 以降でクエリ式のより柔軟な構成をサポートすることを目的としたライブラリ を開発しました。これは、標準のクエリ ビルダーをオーバーロードするドロップイン置換として意図されています。
Tomas の例は次のように変更できます。
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 番目のクエリにスプライスします。ただし、これは引用符で囲まれたクエリ式になり、デフォルトではQueryBuilder
単一のクエリに変換できない可能性があります。q2
query { for p in (query { for p in ctx.Products do
select p }) do
where (p.UnitPrice.Value > 100.0M) }
これは (Tomas の元のコードのように) すべての製品をメモリにロードし、メモリ内で選択を行うことによって評価される可能性がありますが、実際に必要なのは次のようなものです。
query { for p in ctx.Products do
where (p.UnitPrice.Value > 100.0M) }
これは SQL 選択クエリになります。 FSharpComposableQuery
をオーバーライドしQueryBuilder
て、特に変換を実行します。そのため、引用と反引用を使用してクエリをより自由に構成できます。
プロジェクトのホームページはこちら: http://fsprojects.github.io/FSharp.Linq.ComposableQuery/
また、動的クエリに関する別の (古い) 質問に提供したばかりの回答には、さらにいくつかの議論があります: F# でクエリ式を作成するにはどうすればよいですか?
コメントや質問 (特に何かが壊れたり、うまくいくはずの何かがうまくいかない場合) は大歓迎です。
[編集: 「実験的」という言葉を削除するために変更されたばかりのプロジェクト ページへのリンクを更新しました。]
<@ foo %bar @>
F# 3.0 では、クエリは自動的に引用されるため、クエリの作成を可能にする引用スプライシング (構文) を使用することはできません。スプライシングを使用してクエリを作成することで作成できることのほとんどは、以前のソースから新しいクエリを作成し、つまりフィルタリングを追加することで、「通常の LINQ の方法」で実行できます。
// 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) }
このようにして、動的に条件を追加したり、射影を動的に指定したり ( を使用select
) したり、その他のクエリ構成をいくつか実行したりできます。ただし、明示的な引用の場合のように、クエリを作成する完全な柔軟性は得られません。これは、F# 3.0 が C# に存在するものと同様の単純な構文のために支払わなければならない代償だと思います。
query.Select
原則として、 (etc.) 演算子を使用して明示的にクエリを記述できる必要があります。これは明示的な引用符を使用して記述されるため、スプライシングを使用できるはずです。ただし、翻訳がどのように機能するのか正確にはわからないため、実際のサンプルを提供することはできません. このようなものは機能するはずです (ただし、構文は非常に醜いため、文字列またはその他の手法を使用する方がよいでしょう):
<@ 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
F# 3.0 のクエリは に基づいているため、C# で実装したIQueryable
のと同じトリックを使用できる可能性があります。ただし、一部の詳細は異なると思いますので、すぐに機能することは期待できません。そのアイデアの最適な実装はLINQKitにありますが、F# では直接機能しないと思います。
したがって、一般的に、うまく機能する唯一のケースは最初の例だと思います。複数のクエリを記述して、追加のクエリ演算子をクエリに適用するだけです。