2010-08-12 7 views
1

Je suis à l'écoute d'auditer les événements dans NHibernate, en particulier pour OnPostUpdateCollection(PostCollectionUpdateEvent @event)Itérer par les articles IPersistentCollection

Je veux itérer les éléments @event.Collection. La collection @ event.Collection est un IPersistenCollection qui n'implémente pas IEnumerable. Il y a la méthode Entries qui renvoie un IEnumerable, mais il faut un ICollectionPersister auquel je n'ai aucune idée d'où je peux en trouver un.

Les questions sont déjà posées ici: http://osdir.com/ml/nhusers/2010-02/msg00472.html, mais il n'y avait pas de réponse concluante.

Merci à l'avance

Répondre

5

Pedro,

Recherche du code NHibernate je pouvais trouvé le doc suivant sur la méthode GetValue de IPersistentCollection (@ de event.Collection):

/// <summary> 
/// Return the user-visible collection (or array) instance 
/// </summary> 
/// <returns> 
/// By default, the NHibernate wrapper is an acceptable collection for 
/// the end user code to work with because it is interface compatible. 
/// An NHibernate PersistentList is an IList, an NHibernate PersistentMap is an IDictionary 
/// and those are the types user code is expecting. 
/// </returns> 
object GetValue(); 

Avec cela, nous pouvons conclure que vous pouvez lancer votre collection à un IEnumerable et les choses vont bien fonctionner.

J'ai construit un petit échantillon mapper un sac et les choses se sont comme ça ici:

public void OnPostUpdateCollection(PostCollectionUpdateEvent @event) 
{ 
    foreach (var item in (IEnumerable)@event.Collection.GetValue()) 
    { 
     // DO WTVR U NEED 
    } 
} 

Hope this helps!

Filipe

+1

fonctionne très bien! La seule chose à remarquer est que cast à IList. En utilisant une collection mappée comme Set au lieu de Bag, l'interface est ICollection, nous devrions donc utiliser IEnumerable à la place. Merci! – Pedro

+0

Bon point. Changé ma réponse à IEnumerable. – jfneis

2

Si vous devez faire des opérations plus complexes avec la collection, vous allez probablement avoir besoin de la collection persister, que vous pouvez réellement obtenir avec la méthode d'extension suivante (essentiellement, vous avez besoin de travailler autour de la la visibilité par la méthode AbstractCollectionEvent.GetLoadedCollectionPersister):

public static class CollectionEventExtensions 
{ 
    private class Helper : AbstractCollectionEvent 
    { 
     public Helper(ICollectionPersister collectionPersister, IPersistentCollection collection, IEventSource source, object affectedOwner, object affectedOwnerId) 
      : base(collectionPersister, collection, source, affectedOwner, affectedOwnerId) 
     { 
     } 

     public static ICollectionPersister GetCollectionPersister(AbstractCollectionEvent collectionEvent) 
     { 
      return GetLoadedCollectionPersister(collectionEvent.Collection, collectionEvent.Session); 
     } 
    } 

    public static ICollectionPersister GetCollectionPersister(this AbstractCollectionEvent collectionEvent) 
    { 
     return Helper.GetCollectionPersister(collectionEvent); 
    } 
} 

Hope it helps!

Cordialement,
Oliver Hanappi

+0

Très gentil, je voudrais pouvoir l'emporter deux fois – Pedro