2009-08-25 4 views
13

これは簡単な質問でなければなりません。基準が与えられた場合、その基準を満たすエンティティを削除する方法は?どのように基準を使用してNHibernateオブジェクトを削除できますか?

根拠:

HQLとNH基準はNHibernateは、特定の構築物であり、そのようなものとして、それらは、サーバー側のDALの実装の詳細です。私は彼らがクライアント側に「漏れる」ことを望んでいません。したがって、クライアント側では、処理するサーバーにLINQ式を提供します。今まで、NHibernateへの選択要求とLINQの要求は、それらをうまく処理しました。

ただし、今すぐバッチ削除操作を実装する必要があります。通常通り、クライアント側はLINQ式を提供し、サーバーは式を満たすエンティティを削除します。 残念ながら、NHibernateへのLINQはここでは役に立たない。できるだけ多くは、与えられたLINQ式をNHibernateの基準に変換することです。

とにかく、これは物語です。私はクライアント側がNHibernateをまったく知らないことを強調したいと思います。私はこれをそのままにしておきたいと思います。

P.S.私はあなたのリポジトリ/ DAO/PersistenceManagerのでは

答えて

-3

NH 2.1を使用しています

/どんなクラス:

public IEnumerable<T> FindAll(DetachedCriteria criteria) 

     { 

      return criteria.GetExecutableCriteria(Session).List<T>(); 

     } 

、その後

public void Delete(DetachedCriteria criteria) 

     { 

      foreach (T entity in FindAll(criteria)) 

      { 

       Delete(entity); 

      } 

     } 

参照デイビーブリオンのポストData Access with NHibernate

編集

あなたが基準を使用したい場合は私の知る限りでは、あなたがオブジェクトをロードし、それらを削除するためにそれらを反復する必要があります。または、HQLを使用するか、SQLをセッションに渡します。

+6

大量のオブジェクトを扱う場合、データベースからすべてのエンティティをフェッチしてから削除する必要があるため、この方法は嫌いです。 –

+3

これは本当です.HQLを使用して 'DELETE FROM WHERE' SQL文を発行する必要はありませんか? – DanB

+2

みんな、あなたは深刻ではない。より良い方法が必要です! – mark

7

要素のIDを選択し、文字列に結合し、削除するためにHQLを使用する基準を使用できますか?

のような何か:

public void Delete(ICriteria criteria, string keyName, string tableName) 
{ 
    criteria.setProjection(Projections.Attribute(keyName)); 
    IList<int> itemIds = criteria.List<int>(); 

    string collection = string.Join(",", Array.ConvertAll<int, string>(itemIds, Convert.ToString)); 

    Session.HQL(string.Format("delete from {0} where {1} in ({2})", tableName, keyName, collection); 
} 

このコードは(特に私はHQLセクションのわからないんだけど)、私はあなたのアイデアを得たことを考えてテストしたりコンパイルされませんでした。私たちは、フェッチしません。全体のオブジェクトは、投影のおかげで、インデックスだけです。

+1

データベースへの2回の往復を意味しますか?そうであれば、ネイティブSQLは単純に1つだけであるため、十分ではありません。 – mark

+1

まだN + 1よりも優れています.../ – madprog

3

簡単に言えば、2.1.2まではできません。

ただし、LINQ式をHQL(またはICriteriaからHQL)に変換できる場合は、渡されたHQL文字列を使用するオーバーロードされたISession.Delete()メソッドを使用できます。

+0

NHibernateへのLINQはHQLの代わりにCriteriaにLINQを変換するのは不思議そうではありませんが、後者は想定されていますもっと強力になる?結局のところ単純ではないかもしれません。 – mark

+0

HQLはCriteriaよりも強力であるとは言えません。逆もまた同様です。これらは単なる2つの異なる構造です。通常は、別々の目的で使用されます.HQLは特定の一意のクエリであり、クエリを作成して文字列の連結を避けるための条件、DetachedCriteriaによるモジュールサポート、さらにはマッピングに近いものです。 by-exampleの構文も甘いですが、実際にはほとんど使われません。とにかく、私はnhibernateのためのLINQを使用していない - そう - 私は与えるための例がありません。それにもかかわらず、新しいバージョンがあなたが望むものをサポートするまで、Criteriaはselectステートメントのためだけです。 – Jaguar

-5

これは古い質問ですが、議論のためです。コードリポジトリのインターフェースを使用して、また、例えばEntity Frameworkのリポジトリを実装することができますので、十分に汎用的なものにするために式を使用している

public void Delete(System.Linq.Expressions.Expression<System.Func<TEntity, bool>> predicate) 
{ 
    var entities = _session.Query<TEntity>().Where(predicate); 
    foreach (var entity in entities) 
     _session.Delete(entity); 
} 

注:1は、リポジトリのパターンを使用する場合は、次の処理を行いdeleteメソッドを宣言することができます。

+4

かなりです。あなたがしているのは、表現を使ってエンティティを取得し、それを一つずつ削除することです。これは、式でエンティティを削除することではありません。つまり、式を受け取り、それぞれの削除SQL文に変換してから、すべてのエンティティを一度に削除するネイティブAPIを使用することです。 – mark

+2

これは、多くのオブジェクトを持っているときにどうやってうまくいかないのかという大きな警告が必要です。 –

関連する問題