NHibernateとLINQ to SQL


117

実際のプロジェクトでどちらのテクノロジーも使用したことがない人として、これら2つがどのように互いに補完し合い、それらの機能がどの程度重複しているかを誰かが知っているだろうか?

回答:


113

LINQ to SQLでは、クラスごとのテーブルパターンを使用する必要があります。このパターンを使用する利点は、迅速かつ簡単に実装でき、既存のデータベース構造に基づいてドメインを実行するのにほとんど労力を要しないことです。単純なアプリケーションの場合、これは完全に受け入れ可能です(多くの場合はさらに望ましい)が、より複雑なアプリケーションの場合、開発者はドメイン駆動設計の使用を提案することがよくあります。代わりにパターンの(NHibernateが容易にすることです)。

クラスごとのテーブルパターンの問題は、データベース構造がドメイン設計に直接影響することです。たとえば、顧客の主要な住所情報を保持する次の列を持つCustomersテーブルがあるとします。

  • 住所
  • 状態
  • 郵便番号

ここで、顧客のメールアドレスの列も追加して、次の列をCustomersテーブルに追加するとします。

  • MailingStreetAddress
  • MailingCity
  • MailingState
  • MailingZip

LINQ to SQLを使用すると、ドメイン内のCustomerオブジェクトは、これらの8つの各列のプロパティを持つことになります。しかし、ドメイン主導の設計パターンを使用している場合は、おそらくAddressクラスを作成し、Customerクラスに2つのAddressプロパティ(1つは郵送先アドレス用、もう1つは現在のアドレス用)を保持させることになります。

これは単純な例ですが、クラスごとのテーブルパターンがやや臭いドメインにつながる可能性があることを示しています。最後に、それはあなた次第です。繰り返しますが、基本的なCRUD(作成、読み取り、更新、削除)機能のみを必要とする単純なアプリの場合、LINQ to SQLは単純であるため理想的です。しかし、個人的には、NHibernateを使用することが好きです。それは、よりクリーンなドメインを容易にするためです。

編集:@lomaxx-はい、私が使用した例は単純化されており、LINQ to SQLで適切に機能するように最適化されている可能性があります。私はポイントを家に帰るためにそれをできるだけ基本的に保ちたかったです。ただし、データベース構造でドメイン構造を決定することが悪い考えである、または少なくとも最適化されていないOO設計につながるシナリオがいくつかあるという点は依然として残っています。


4
Linq To SQLを使用してリポジトリの実装をコーディングできます。これは非常に便利です。
Nicolas Dorier、2009年

1
それはActiveRecordではないと思います。マップされたクラスでさえ、インフラストラクチャロジックの一部をカプセル化しています。ActiveRecordパターンは、Customer.Save()がある場合です。L2Sは、nHibernateのSessionのように、DataContextクラスを使用して作業単位パターンを実装しますが、NHには実際のPOCOアプローチがあります。
Hrvoje Hudo

1
@kevin "LINQ to SQLはアクティブなレコードパターンを使用します"不正解です。それは、ADO.NETがアクティブレコードを使用する、またはNHibernateがアクティブレコードを使用するというようなものです。これらはすべてデータアクセステクノロジーであり、特定のデータアクセスパターンを強制するものではありません。個人的には、リポジトリパターンでlinq-to-sqlを使用するのが好きです。linq-to-sqlがNHibernateのような複雑なマッピングをサポートしていないことは正しいです。
liammclennan

1
代わりにデータベースを正規化して、DALをSQLMetalなどのツールで生成できるようにしたらどうでしょうか。
Alex

3
@CoffeeAddictインピーダンスの不一致が大きすぎて耐えられない場合は、アプリケーションが複雑すぎてLINQ to SQLを使用できない場合です。私の例が臭いのは、LINQ to SQLを使用すると2ではなく8のプロパティが生成され、Addressクラスを取り込む関数の実装や、Addressクラスのルーチンの実装など、実行できる機能が制限されるためです。 NHibernateを使用していた場合は行います。
Kevin Pang 2010

26

これまでに見逃されてきた2つのポイント:

  • LINQ to SQLは、OracleまたはSqlServer以外のデータベースでは機能しません。 ただし、サードパーティはOracleに対するより優れたサポートを提供しています。たとえば、devArtのdotConnectDbLinqMindscapeのLightSpeedおよびALinqです。(私はこれらについて個人的な経験はありません)

  • Linq to NHibernateを使用すると、NhiberateでLinqを使用できるため、使用しない理由が削除される場合があります。

また、Nhibernateへの新しい流暢なインターフェイスにより、Nhibernateのマッピングを構成するのが簡単になったようです。(Nhibernateの問題点の1つを取り除く)


更新

Linq to Nhiberateは、現在アルファ版であるNhiberate v3でより優れています。Nhiberate v3は今年の終わりに出荷される可能性があるようです。

.net 4以降のエンティティフレームの機能も、実際のオプションのように見え始めています。


2
Linq to NHibernateはまだ非常に初期の段階です。これは完全な実装ではなく、間違いなく本番環境で使用する準備ができていません。
liammclennan 2009

新しいLinqConnect 2.0リリースでは、タイプごとの継承のサポート、PLINQのサポート、バッチ更新機能など、便利な機能がいくつか追加されています。ORMデザイナー(Devartエンティティ開発者)は、Model Firstのサポートとマッピング同期機能を備えています。詳細:devart.com/news/2010/dotconnects600.html
Devart

23

@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
はこれを自動的に行うことができます。


15
他のアプリをサポートしているため変更できないレガシーデータベース構造に対してコードを記述している場合はどうでしょうか。ドメインモデルが貧弱なデータベース設計を継承するようにしたいですか、それともデータベース構造とは独立して変化できるリッチドメインモデルを作成したいですか?
Larry Foulkrod、2008年

7

Fluent NHibernateは、単純な規則に基づいてマッピングファイルを生成できます。XMLの記述はなく、厳密に型指定されています。

私は最近、パフォーマンス上の理由からLinq To SQLからNHibernateに変更する必要があるプロジェクトに取り組みました。特に、オブジェクトを具体化するL2Sの方法は、NHibernateの同上よりも遅く、変更管理も非常に低速です。また、変更管理が不要な特定のシナリオでは、変更管理をオフにするのが難しい場合があります。

DataContextから切断されたエンティティを使用する場合(たとえば、WCFシナリオなど)、変更を更新するためにそれらをDataContextに再度接続するのに多くの問題が発生する可能性があります。私はNHibernateでそれに関して問題を抱えていません。

L2Sで見逃してしまうのは、エンティティの両端の関係を最新に保つコード生成です。しかし、NHibernateがそれを実行するためのツールもいくつかあると思います...


2
念の他人に自分の記事を読んで、あまりにも船をジャンプを考えている- .ObjectTrackingEnabled = falseあなたの上のDataContext問題を追跡し、あなたの変更を解決しているだろう。作業単位パターンを購入してDDDを実行しない限り、Linq-to-SQLは本当に役立ちます。
mattmc3 2010

パフォーマンス上の理由から、Linq To SQLからNHibernateに変更する必要がありました」-[Fluent、それ以上] NHibernateを数年間使用してきたので、私はあなたのために感じています。だいたい私たちはだまされて、実際のパフォーマンスのプレッシャーポイントのためにネイティブSQLを作成することになったと思います。移行の進捗状況(6年後...)を聞いて、移行の価値があったかどうかを聞いてみると面白いでしょう。
ルフィン、

5

「LINQ」の意味を明確にしていただけますか?

LINQはデータアクセステクノロジーではなく、ネイティブコンストラクトとしてクエリをサポートする言語機能にすぎません。特定のインターフェイス(IQueryableなど)をサポートする任意のオブジェクトモデルを照会できます。

多くの人がLINQ To SQLをLINQと呼んでいますが、それはまったく正しくありません。マイクロソフトは.NET 3.5 SP1を備えたLINQ To Entitiesをリリースしました。さらに、NHibernateにはLINQインターフェイスがあるため、LINQとNHibernateを使用してデータを取得できます。


2

LINQは、LINQ to SQLを意味していると思います。これは、LINQ自体には、それに関連するデータベースが存在しないためです。これは、SQLっぽく見えるようにするためにボートにロードされたsyntac sugarを備えたクエリ言語にすぎません。

基本的な例の非常に基本的な例では、NHibernateとLINQ to SQLはどちらも同じ問題を解決しているようです。合格すると、NHibernateが真にリッチなドメインモデルの作成を可能にする多くの機能をサポートしていることがすぐにわかります。LINQ to NHibernateプロジェクトもあり、LINQ to SQLを使用する場合とほぼ同じ方法で、LINQを使用してNHibernateにクエリを実行できます。


1

まず、2つのことを分けましょう。データベースモデリングはデータに関係し、オブジェクトモデリングはエンティティと関係に関係します。

Linq-to-SQLの利点は、データベーススキーマからクラスをすばやく生成して、それらをアクティブレコードオブジェクトとして使用できるようにすることです(アクティブレコードの設計パターン定義を参照)。

NHibernateの利点は、オブジェクトモデリングとデータベースモデリングの間の柔軟性を可能にすることです。データベースは、たとえばパフォーマンスを考慮して、データを最もよく反映するようにモデル化できます。オブジェクトモデリングは、ドメイン駆動設計などのアプローチを使用してビジネスルールの要素を最もよく反映します。(Kevin Pangのコメントを参照)

モデリングや命名規則が不十分なレガシーデータベースでは、Linq-to-SQLはこの不要な構造と名前をクラスに反映します。ただし、NHibernateはこの混乱をデータマッパーで隠すことができます。

データベースのネーミングが適切で、複雑度が低いグリーンフィールドプロジェクトでは、Linq-to-SQLが適切な選択になります。

ただし、慣例としてマッピングを使用するこの同じ目的で、自動マッピングFluent NHibernateを使用できます。この場合、XMLまたはC#のデータマッパーについて心配する必要はなく、NHibernateに、カスタマイズ可能な規則に基づいてエンティティからデータベーススキーマを生成させます。

一方、Linq-to-SQLの学習曲線はNHibernateよりも小さくなっています。


0

または、Castle ActiveRecordsプロジェクトを使用することもできます。私はこれを少し使って、レガシープロジェクトの新しいコードを増やしています。それはNHibernateを使用し、アクティブなレコードパターンで動作します(私が知っている名前を考えると驚くべきことです)。私は試していませんが、一度使用したら、NHibernateのサポートを直接停止する必要があると感じた場合、プロジェクトの一部またはすべてを行うにはそれほど多くはないでしょう。


0

「どちらも使ったことがない人のために」と書いたように、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ではサポートされていません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.