2009-12-08 7 views
10

Quelle est la meilleure pratique pour ce problème? Y a-t-il des fonctionnalités de traitement par lots intégrées?Comment supprimer plusieurs entités DB avec Nhibernate?

Exemple de code:

using (ITransaction transaction = _session.BeginTransaction()) 
{ 
    _session.Delete("FROM myObject o WHERE o.Id = IN(1,2,...99999)"); 
    transaction.Commit(); 
} 

Merci à l'avance.

Répondre

17

HQL soutient la clause IN, et si vous utilisez setParameterList vous pouvez même passer dans une collection.

var idList = new List<int>() { 5,3,6,7 }; 

_session.CreateQuery("DELETE myObject o WHERE o.Id = IN (:idList)") 
    .SetParameterList("idList", idList) 
    .ExecuteUpdate(); 
+0

Que faire si l'idList est énorme? Comment feriez-vous en lots autour de lui? ou nhibernate at-il une forme de loterie intégrée? – Newbie

+0

Je devrais configurer un test en utilisant nHibernate profiler [nhprof.com] pour voir ce qui est réellement émis dans la BD, mais si je devais deviner, je dirais que cela ressemblerait explicitement à votre exemple codé en dur. – joshperry

+2

Vous pouvez définir une taille de lot dans votre : 100. Cependant, en fonction de votre HQL, je suppose que c'est juste une requête émise (les lots s'appliqueraient si vous étiez en boucle dans une collection et appeliez Delete sur eux). – ddango

5

vous pouvez utiliser HQL supprimer plusieurs objets

Look for delete here - for session.delete example

HQL SUPPRIMER exemple (vous pouvez utiliser avec HQL):

ISession session = sessionFactory.OpenSession(); 
ITransaction tx = session.BeginTransaction(); 

String hqlDelete = "delete Customer c where c.name = :oldName"; 
// or String hqlDelete = "delete Customer where name = :oldName"; 
int deletedEntities = session.CreateQuery(hqlDelete) 
     .SetString("oldName", oldName) 
     .ExecuteUpdate(); 
tx.Commit(); 
session.Close(); 
9

J'ai eu des problèmes pour obtenir la réponse au travail et je trouve la requête suivante a travaillé 100%

 Session.CreateQuery("delete Customer c where c.id in (:deleteIds)") 
      .SetParameterList("deleteIds", deleteIds) 
      .ExecuteUpdate(); 

client est le nom de la classe et non le nom de la table. id est minuscule et en HQL c'est la clé primaire pas un nom de propriété dans la classe (les noms de propriété sont supportés)

+0

Oui, et la seule mise en garde qui mérite d'être mentionnée est que la cascade ne sera pas appliquée puisque vous ne chargez pas l'objet. Donc, si le client a une ligne d'adresse attachée et qu'elle supprime normalement en cascade, cela ne va pas honorer – PandaWood

Questions connexes