17

LINQtoSQLまたはLINQtoEntitiesには、LINQをSQLテキスト文字列に変換する機能がすでにあります。しかし、両方のプロバイダーが必要とするdbコンテキスト(つまり、アクティブなデータベース接続を意味する)を使用せずに、アプリケーションで変換を実行する必要があります。

WHERE次のリポジトリインターフェイスを機能させるために、LINQ式をDBコンテキストの依存関係なしに、および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」および「ORDERBY」ステートメント)をカバーする可能性があります。

しかし同時に、これを行うために独自のカスタムコードを作成する必要はないと感じています。私が自分で書くのに行き詰まっている場合でも、誰かが私が反映して模倣できる特定のクラス(NHibernate、EFなど)を教えてくれるかどうか興味があります。必要な部分を見つけるためだけに大規模なツールのコードをふるいにかけるのに何時間も費やしたくないので、あなたがそれらを知っているなら、私は覗くべき特定のクラスについて尋ねています。

それは重要ではありませんが、なぜ私がLINQtoSQLやLINQtoEntitiesを使用していないのかを知りたい場合は、特定のアプリケーションではDapperなどのツールを使用することをお勧めします。

ユースケース自分でツールの作成を完了した場合でも、サードパーティのライブラリを見つけた場合でも、「 LINQtoSQL テキスト文字列」が役立つ理由は次のとおりです。

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

つまり、このようなツールは、DDDに準拠したリポジトリの「仕様」または「クエリオブジェクト」の概念を実現するのに役立ち、SQLへのEFまたはLINQに依存することなく実現します。

4

3 に答える 3

4

IQueryableこれを適切に行うことは非常に複雑です。特に、現時点では、式ツリー(クエリを表すために使用されるもの)についてあまり知らないようです。

しかし、本当に始めたい場合(または、それがどれだけの作業になるかを知りたい場合)は、MattWarrenの17部構成のシリーズ「IQueryableプロバイダーの構築」を参照してください。

于 2013-03-05T18:59:00.697 に答える
2

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

これらすべてが障壁ではない場合、この演習は、少なくとも最初の1か月ほどは、実際には非常に楽しく、やりがいのあるものになる可能性があります。私が気付いたこれらのプロバイダーの一般的な問題の1つは、最初の柔軟性の欠如と疑わしい設計の選択が、後の困難やハッキーな修正などにつながったことです。可能な限り事前に計画し、プロセス全体、さまざまな段階、コンポーネントを適切に識別します。そして懸念はこれを開発することをはるかに容易にするでしょう。あるプロバイダーで私が見た最大の間違いは、出力クエリをその部分に分解できなかったことです。select、from、where、orderbyです。各パーツは、全体を通して独自のオブジェクトで表され、最後にまとめられる必要があります。このアプローチについては、以下にリンクされているシリーズでプロバイダーを作成する方法に関するエンドツーエンドのチュートリアルで説明します。サンプルプロジェクトが含まれており、簡略化された/チュートリアルのバリアントと、プロジェクト用にゼロから作成されたフルバージョンが含まれています。それについて書く時間を見つけること自体が挑戦でした。

于 2015-07-03T03:40:33.420 に答える
1

これは私がかなり前に簡単に調べたものです。アイデアについては、 http ://iqtoolkit.codeplex.com/および/またはhttp://expressiontree.codeplex.com/を参照してください。他の人が述べているように、スコープを本当に必要な機能の最小限のセットに制限しない限り、Linqクエリプロバイダーの構築は簡単ではありません。

目標がDDDに従ったリポジトリの「仕様」または「クエリオブジェクト」の概念に関連している場合、これは最善の方向ではない可能性があります。テクノロジー関連の抽象化のようなCRUDの代わりに、テクノロジー関連の抽象化への直接的な依存を最小限に抑えながら、ドメインの動作を表現できる方法に焦点を当てた方が生産性が高い場合があります。Eric Evansが最近議論したように、彼はDDDの最初の説明で、リポジトリなどの技術的な構成要素に焦点を合わせたことを後悔しています。

于 2013-07-12T03:14:23.120 に答える