c# - パフォーマンス - vb net linq select tostring




DBコンテキストなしでLINQ式をSQLテキストに変換 (2)

LINQ to SQLまたはLINQ to Entitiesのいずれかに、LINQをSQLテキスト文字列に変換する機能がすでにあります。 しかし、私は自分のアプリケーションがdbコンテキストを使用せずに変換を行うことを望んでいます。つまり、これらのプロバイダは両方とも要求するアクティブなデータベース接続を意味します。

DBコンテキストに依存せずに、LINQ式をWHERE句とORDER BY句の同等のSQL文字列に変換して、次のリポジトリインタフェースを機能させます。

public interface IStore<T> where T : class 
{
     void Add(T item);
     void Remove(T item);
     void Update(T item);
     T FindByID(Guid id);

     //sure could use a LINQ to SQL converter!
     IEnumerable<T> Find(Expression<Func<T, bool>> predicate);
     IEnumerable<T> FindAll();
}

質問

私が興味を持っているのは、主に式ツリーのトラバースと変換です。そのようなカスタムコンテキストで使用するために組み込むことができる既存のライブラリ(nuget?)を知っている人はいますか?

それはすでに私の上記のリポジトリで動作するSQLの例にこの式のツリーに似ている私自身の作業 "LINQはSQLテキストに変換"ツールを構築しているので。 それは私がこのようなコードを書くことを可能にします:

IRepository<Person> repo = new PersonRepository();
var maxWeight = 170;
var results = repo.Find(x => (x.Age > 40 || x.Age < 20) && x.Weight < maxWeight);

しかし、私のコードとそのサンプルは原始的なものです(そしてそのサンプル自体はLINQ to SQL dbコンテキストに依存しています)。 たとえば、どちらも "LIKE"ステートメントの生成を処理しません。

考えられるすべてのLINQクエリを処理するジェネレータツールは必要ありません。 たとえば、結合やインクルードの処理と生成については心配していません。 実際、あと約20時間で、私自身のカスタムコードが私が気にするすべてのケースをカバーするかもしれません(ほとんどの場合 "WHERE"と "ORDER BY"ステートメント)。

しかし同時に私はこれをするために私自身のカスタムコードを書く必要はないと思う。 私が自分のものを書いているのをやめた場合、誰かが私が反省し模倣することができる特定のクラス(NHibernate、EFなど)を私に指摘することができれば私はまだ興味があるでしょう。 私が必要とする部分を見つけるためだけに大規模なツールのコードを見ていくことに時間を費やしたくないので、私はあなたがそれらを知っていれば、覗くべき特定のクラスについて尋ねています。

問題ではありませんが、LINQ to SQLやLINQ to Entitiesを使用していない理由を知りたい場合は、 Dapperなどのツールを使用することをおDapperます。

使用例自分でツールを作成し終えた場合でも、サードパーティのライブラリを見つけた場合でも、 "LINQ to SQLテキスト文字列"が便利な理由は次のとおりです。

  • IRepository.Findメソッドに入力した述語には、インテリセンスと基本的なコンパイル時チェックがあります。
  • 私が提案したIStoreインターフェースはDBアクセスまたはWebサービスアクセス用に実装できます。 わかりやすくするために、LINQの "WHERE / ORDER BY"述語をSQLの "WHERE / ORDER BY"句に変換できるとします。
    • SQL文字列はDapperによって直接使用される可能性があります。
    • LINQ式とは異なり、SQL文字列をWCFサービスに送信して直接DBアクセスに使用することができます(これ自体はDapperを使用していない可能性があります)。
    • SQL文字列は、 カスタムコードを使用して、WCFサービスによってLINQステートメントに逆シリアル化することができます。 Eric Lippertはこれについてコメントしています。
  • UIはIQueryableメカニズムを使用して、リポジトリに渡す述語を動的に生成できます。

要するに、そのようなツールは、DDDに従ったリポジトリの「仕様」または「クエリオブジェクト」の概念を満たすのに役立ち、EFまたはLINQ to SQLに依存することなくそうします。


これはかなり経験豊富な.NET開発者にしか適していないかなりの量の作業なので確認できます。 C#に関する完全な知識、T-SQLを含む複数言語の経験が必須です。 C#(またはVB.NET)とT-SQLの両方に精通している必要があります。後者は、前者を使用してトランスレータを記述する必要があるためです。 さらに、これはメタプログラミングの分野にあります。メタプログラミングは、コンピュータサイエンスのかなり高度な分野と考えられています。 多くの抽象的な考え方が関係しています。 抽象的な概念の層が互いに積み重ねられています。

これらすべてが障壁ではない場合、この演習は実際には非常に楽しくてやりがいのあるものになる可能性があります(少なくとも最初の1か月ほど)。 私が気付いたこれらのプロバイダのよくある問題の1つは、最初の柔軟性の欠如と疑わしい設計の選択が後の困難やハックな修正などを招いたことです。そして懸念はこれを開発することをはるかに容易にするでしょう。 あるプロバイダで私が目にした最大の間違いは、出力クエリをその部分に分割できなかったことです - select、from、where、order byです。 各部分は全体を通してそれ自身のオブジェクトによって表され、そして最後にまとめられるべきです。 私はこのアプローチを、以下にリンクされているシリーズの中でプロバイダーを書く方法についての私のエンドツーエンドのチュートリアルで説明します。 サンプルプロジェクトが含まれていて、単純化された/チュートリアルの変形とプロジェクトのために最初から作られたフルバージョンがあります。 それについて書く時間を見つけることはそれ自体が課題でした。


これは私がしばらく前に簡単に調べたものです。 アイデアについては、 http://expressiontree.codeplex.com/http://expressiontree.codeplex.com/http://iqtoolkit.codeplex.com/ http://expressiontree.codeplex.com/ 。 他の人が言及したように、あなたがあなたの範囲をあなたが本当に必要とする機能の最小のセットに制限しないならば、Linq質問プロバイダー構築はささいなことから遠く離れています。

あなたの目標がDDDによるリポジトリの "仕様"または "クエリオブジェクト"の概念に関連している場合、これは取るべき最良の方向ではないかもしれません。 テクノロジ関連の抽象化のようなCRUDの代わりに、テクノロジ関連の抽象化への直接的な依存を最小限に抑えて、ドメインの動作を表現できる方法に焦点を当てる方が生産的です。 Eric Evansが最近議論したように、彼は最初のDDDの説明の中で、リポジトリのような技術的な構成要素に焦点を当てていることを遺憾に思います。





expression-trees