2010-07-14 4 views
1

Je n'arrive pas à trouver les enfants à ajouter, à mettre à jour et à supprimer quand j'ai affaire à deux listes, l'une avec les anciens enfants (de db) et l'autre liste avec les enfants modifiés (à partir de l'entrée de l'utilisateur).Traiter les collections avec les relations parent-enfant dans NHibernate

Actuellement, je dois parcourir les listes et comparer pour trouver la différence.

Est-ce que quelqu'un connaît une meilleure façon de le faire sans avoir à parcourir les listes?

Répondre

6

La méthode d'extension IEnumerable.Except est parfaite pour cela. Dans la plupart des cas, vous devrez utiliser la surcharge qui accepte un IEqualityComparer<T> pour comparer par identité, sauf si vous avez soigneusement substitué Equals et GetHashCode dans vos objets.

Compte tenu

IEnumerable<Company> oldList, IEnumerable<Company> newList 

Le code est:

var companiesToAdd = newList.Except(oldList).ToArray(); 
var companiesToRemove = oldList.Except(newList).ToArray(); 

Les ToArray() appels sont là pour que vous puissiez apporter des modifications à la liste initiale en réitérant l'ajout et de suppression des listes.

Edit: Voici deux classes d'utilitaires qui facilitent cette opération. L'utilisation est

var diff = new DiffIEnumerable<Company>(oldList, newList, x => x.CompanyId); 
var companiesToAdd = diff.InYNotX; 
var companiesToRemove = diff.InXNotY; 

public class IdentityComparer<T> : IEqualityComparer<T> where T : class 
{ 
    private readonly Func<T, object> _getIdentity; 

    public IdentityComparer(Func<T, object> getIdentity) 
    { 
     _getIdentity = getIdentity; 
    } 

    public bool Equals(T x, T y) 
    { 
     if (x == null || y == null) 
     { 
      return false; 
     } 
     return _getIdentity(x).Equals(_getIdentity(y)); 
    } 

    public int GetHashCode(T obj) 
    { 
     return _getIdentity(obj).GetHashCode(); 
    } 
} 

public class DiffIEnumerable<T> where T : class 
{ 
    public DiffIEnumerable(IEnumerable<T> x, IEnumerable<T> y, Func<T, object> getIdentity) : 
     this(x, y, new IdentityComparer<T>(getIdentity)) 
    { } 

    public DiffIEnumerable(IEnumerable<T> x, IEnumerable<T> y, IEqualityComparer<T> comparer) 
    { 
     InXAndY = x.Intersect(y, comparer).ToArray(); 
     InXNotY = x.Except(y, comparer).ToArray(); 
     InYNotX = y.Except(x, comparer).ToArray(); 
    } 

    public IEnumerable<T> InXAndY { get; private set; } 

    public IEnumerable<T> InXNotY { get; private set; } 

    public IEnumerable<T> InYNotX { get; private set; } 

} 
+0

C'est assez slick..will ajouterons cela à mon sac-o-tours +1 – DanP

+0

C'est la qualité! merci Jamie. – ctb

Questions connexes