回答:
LINQ to SQLでは、クラスごとのテーブルパターンを使用する必要があります。このパターンを使用する利点は、迅速かつ簡単に実装でき、既存のデータベース構造に基づいてドメインを実行するのにほとんど労力を要しないことです。単純なアプリケーションの場合、これは完全に受け入れ可能です(多くの場合はさらに望ましい)が、より複雑なアプリケーションの場合、開発者はドメイン駆動設計の使用を提案することがよくあります。代わりにパターンの(NHibernateが容易にすることです)。
クラスごとのテーブルパターンの問題は、データベース構造がドメイン設計に直接影響することです。たとえば、顧客の主要な住所情報を保持する次の列を持つCustomersテーブルがあるとします。
ここで、顧客のメールアドレスの列も追加して、次の列をCustomersテーブルに追加するとします。
LINQ to SQLを使用すると、ドメイン内のCustomerオブジェクトは、これらの8つの各列のプロパティを持つことになります。しかし、ドメイン主導の設計パターンを使用している場合は、おそらくAddressクラスを作成し、Customerクラスに2つのAddressプロパティ(1つは郵送先アドレス用、もう1つは現在のアドレス用)を保持させることになります。
これは単純な例ですが、クラスごとのテーブルパターンがやや臭いドメインにつながる可能性があることを示しています。最後に、それはあなた次第です。繰り返しますが、基本的なCRUD(作成、読み取り、更新、削除)機能のみを必要とする単純なアプリの場合、LINQ to SQLは単純であるため理想的です。しかし、個人的には、NHibernateを使用することが好きです。それは、よりクリーンなドメインを容易にするためです。
編集:@lomaxx-はい、私が使用した例は単純化されており、LINQ to SQLで適切に機能するように最適化されている可能性があります。私はポイントを家に帰るためにそれをできるだけ基本的に保ちたかったです。ただし、データベース構造でドメイン構造を決定することが悪い考えである、または少なくとも最適化されていないOO設計につながるシナリオがいくつかあるという点は依然として残っています。
これまでに見逃されてきた2つのポイント:
LINQ to SQLは、OracleまたはSqlServer以外のデータベースでは機能しません。 ただし、サードパーティはOracleに対するより優れたサポートを提供しています。たとえば、devArtのdotConnect、DbLinq、MindscapeのLightSpeedおよびALinqです。(私はこれらについて個人的な経験はありません)
Linq to NHibernateを使用すると、NhiberateでLinqを使用できるため、使用しない理由が削除される場合があります。
また、Nhibernateへの新しい流暢なインターフェイスにより、Nhibernateのマッピングを構成するのが簡単になったようです。(Nhibernateの問題点の1つを取り除く)
更新
Linq to Nhiberateは、現在アルファ版であるNhiberate v3でより優れています。Nhiberate v3は今年の終わりに出荷される可能性があるようです。
.net 4以降のエンティティフレームの機能も、実際のオプションのように見え始めています。
@Kevin:あなたが提示している例の問題は、データベースの設計が悪いことです。顧客テーブルと住所テーブルを作成し、テーブルを正規化すると思いました。その場合は、提案しているシナリオでLinq To SQLを確実に使用できます。スコットガスリーは、Linq To SQLの使用に関する一連のすばらしい記事を投稿しています。ぜひチェックしてください。
LinqとNHibernateが一緒に使用される可能性があることを意味するため、LinqとNHibernateが互いに補完し合うとは言えないでしょう。
NHibernateを使用すると、非常に柔軟な方法でデータベーステーブルをドメインオブジェクトにマップできます。また、HBLを使用してデータベースを照会することもできます。
Linq to SQLでは、ドメインオブジェクトをデータベースにマップすることもできますが、Linqクエリ構文を使用してデータベースをクエリします
ここでの主な違いは、Linqクエリ構文がコンパイラによってコンパイル時にチェックされ、クエリが有効であることを確認することです。
linqについて知っておくべきいくつかのことは、それが.net 3.xでのみ利用可能であり、VS2008でのみサポートされていることです。NHibernateは2.0と3.x、およびVS2005で使用できます。
NHibernateについて知っておくべきいくつかのことは、ドメインオブジェクトを生成しないこと、およびマッピングファイルを生成しないことです。これは手動で行う必要があります。Linq
はこれを自動的に行うことができます。
Fluent NHibernateは、単純な規則に基づいてマッピングファイルを生成できます。XMLの記述はなく、厳密に型指定されています。
私は最近、パフォーマンス上の理由からLinq To SQLからNHibernateに変更する必要があるプロジェクトに取り組みました。特に、オブジェクトを具体化するL2Sの方法は、NHibernateの同上よりも遅く、変更管理も非常に低速です。また、変更管理が不要な特定のシナリオでは、変更管理をオフにするのが難しい場合があります。
DataContextから切断されたエンティティを使用する場合(たとえば、WCFシナリオなど)、変更を更新するためにそれらをDataContextに再度接続するのに多くの問題が発生する可能性があります。私はNHibernateでそれに関して問題を抱えていません。
L2Sで見逃してしまうのは、エンティティの両端の関係を最新に保つコード生成です。しかし、NHibernateがそれを実行するためのツールもいくつかあると思います...
.ObjectTrackingEnabled = false
あなたの上のDataContext
問題を追跡し、あなたの変更を解決しているだろう。作業単位パターンを購入してDDDを実行しない限り、Linq-to-SQLは本当に役立ちます。
「LINQ」の意味を明確にしていただけますか?
LINQはデータアクセステクノロジーではなく、ネイティブコンストラクトとしてクエリをサポートする言語機能にすぎません。特定のインターフェイス(IQueryableなど)をサポートする任意のオブジェクトモデルを照会できます。
多くの人がLINQ To SQLをLINQと呼んでいますが、それはまったく正しくありません。マイクロソフトは.NET 3.5 SP1を備えたLINQ To Entitiesをリリースしました。さらに、NHibernateにはLINQインターフェイスがあるため、LINQとNHibernateを使用してデータを取得できます。
LINQは、LINQ to SQLを意味していると思います。これは、LINQ自体には、それに関連するデータベースが存在しないためです。これは、SQLっぽく見えるようにするためにボートにロードされたsyntac sugarを備えたクエリ言語にすぎません。
基本的な例の非常に基本的な例では、NHibernateとLINQ to SQLはどちらも同じ問題を解決しているようです。合格すると、NHibernateが真にリッチなドメインモデルの作成を可能にする多くの機能をサポートしていることがすぐにわかります。LINQ to NHibernateプロジェクトもあり、LINQ to SQLを使用する場合とほぼ同じ方法で、LINQを使用してNHibernateにクエリを実行できます。
まず、2つのことを分けましょう。データベースモデリングはデータに関係し、オブジェクトモデリングはエンティティと関係に関係します。
Linq-to-SQLの利点は、データベーススキーマからクラスをすばやく生成して、それらをアクティブレコードオブジェクトとして使用できるようにすることです(アクティブレコードの設計パターン定義を参照)。
NHibernateの利点は、オブジェクトモデリングとデータベースモデリングの間の柔軟性を可能にすることです。データベースは、たとえばパフォーマンスを考慮して、データを最もよく反映するようにモデル化できます。オブジェクトモデリングは、ドメイン駆動設計などのアプローチを使用してビジネスルールの要素を最もよく反映します。(Kevin Pangのコメントを参照)
モデリングや命名規則が不十分なレガシーデータベースでは、Linq-to-SQLはこの不要な構造と名前をクラスに反映します。ただし、NHibernateはこの混乱をデータマッパーで隠すことができます。
データベースのネーミングが適切で、複雑度が低いグリーンフィールドプロジェクトでは、Linq-to-SQLが適切な選択になります。
ただし、慣例としてマッピングを使用するこの同じ目的で、自動マッピングでFluent NHibernateを使用できます。この場合、XMLまたはC#のデータマッパーについて心配する必要はなく、NHibernateに、カスタマイズ可能な規則に基づいてエンティティからデータベーススキーマを生成させます。
一方、Linq-to-SQLの学習曲線はNHibernateよりも小さくなっています。
または、Castle ActiveRecordsプロジェクトを使用することもできます。私はこれを少し使って、レガシープロジェクトの新しいコードを増やしています。それはNHibernateを使用し、アクティブなレコードパターンで動作します(私が知っている名前を考えると驚くべきことです)。私は試していませんが、一度使用したら、NHibernateのサポートを直接停止する必要があると感じた場合、プロジェクトの一部またはすべてを行うにはそれほど多くはないでしょう。
「どちらも使ったことがない人のために」と書いたように、LINQ to SQLは使いやすいので誰でも簡単に使用できます。また、ほとんどの場合に役立つ手順もサポートしています。複数のテーブルからデータを取得してプロシージャを作成し、そのプロシージャをデザイナーにドラッグすると、すべてが作成されるとします。プロシージャ名が「CUSTOMER_ORDER_LINEITEM」であり、これら3つのすべてのテーブルからレコードをフェッチして、次のように書き込みます。
MyDataContext db = new MyDataContext();
List<CUSTOMER_ORDER_LINEITEMResult> records = db.CUSTOMER_ORDER_LINEITEM(pram1, param2 ...).ToList<CUSTOMER_ORDER_LINEITEMResult>();
レコードオブジェクトをforeachループでも使用できますが、NHibernateではサポートされていません。