Différentielle entre deux collection

Soyez le premier à donner votre avis sur cette source.

Vue 3 990 fois - Téléchargée 464 fois

Description

L’extension suivante vous permettra de faire très facilement le différentielle entre deux collection IEnumerable
le but: comparer deux collection, puis identifier les élément "en trop", "en plus" et "a mettre à jour"
les éléments des deux collections doivent implémenter l'interface IPrimaryKey (pour la comparaison des éléments)

exemple d'utilisation:

listA.diffObjectToAdd(listB);
listA.diffObjectToRemove(listB);
listA.diffObjectToUpdate(listB);

Source / Exemple :


// IPrimaryKey :

public interface IPrimaryKey
{
    int PrimaryKeyValue{get;}
}

// Extention :

public static class EnumerableExtention
{

    private static List<int> GetIds(IEnumerable<IPrimaryKey> list)
    {
        if (list == null) return new List<int>();
        return list.Select(it => it.PrimaryKeyValue).ToList();
    }

    public static IEnumerable<T> diffObjectToRemove<T>(this IEnumerable<T> source, IEnumerable<IPrimaryKey> list)
        where T : class, IPrimaryKey
    {
        if (source == null) return new List<T>();
        var listIdsFrom = GetIds(list);
        var listIdsTo = GetIds(source);
        var idsToDelete = listIdsTo.Except(listIdsFrom);
        return source.Where(it => idsToDelete.Contains(it.PrimaryKeyValue)).ToList();
    }

    public static IEnumerable<T> diffObjectToAdd<T>(this IEnumerable<IPrimaryKey> source, IEnumerable<T> list)
        where T : class, IPrimaryKey
    {
        if (list == null) return new List<T>();
        var listIdsFrom = GetIds(list);
        var listIdsTo = GetIds(source);
        var idsToAdd = listIdsFrom.Except(listIdsTo);
        return list.Where(it => idsToAdd.Contains(it.PrimaryKeyValue)).ToList();
    }

    public static IEnumerable<T> diffObjectToUpdate<T>(this IEnumerable<T> source, IEnumerable<IPrimaryKey> list)
        where T : class, IPrimaryKey
    {
        if (source == null) return new List<T>();
        var listIdsFrom = GetIds(list);
        var listIdsTo = GetIds(source);
        var idsToUpdate = listIdsTo.Intersect(listIdsFrom);
        return source.Where(it => idsToUpdate.Contains(it.PrimaryKeyValue)).ToList();
    }
}

Conclusion :


// exemple utilisation :
public class A : IPrimaryKey
{
public int id = 0;

#region IPrimaryKey Members

public int PrimaryKeyValue
{
get { return id; }
}

#endregion
}

public class B : IPrimaryKey
{
public int id = 0;

#region IPrimaryKey Members

public int PrimaryKeyValue
{
get { return id; }
}

#endregion
}

//Dans le code:

List<A> listA = new List<A>();
List<B> listB = new List<B>();

for (var i = 1; i < 10; i++)
{
listA.Add(new A() { id = i });
}

for (var i = 5; i < 15; i++)
{
listB.Add(new B() { id = i });
}


foreach (var item in listA.diffObjectToAdd(listB))
Console.WriteLine("Add: {0} {1}", item.id, item.GetType().Name);

foreach (var item in listA.diffObjectToRemove(listB))
Console.WriteLine("Remove: {0} {1}", item.id, item.GetType().Name);

foreach (var item in listA.diffObjectToUpdate(listB))
Console.WriteLine("Update: {0} {1}",+item.id,item.GetType().Name);

Add: 10 B
Add: 11 B
Add: 12 B
Add: 13 B
Add: 14 B
Remove: 1 A
Remove: 2 A
Remove: 3 A
Remove: 4 A
Update: 5 A
Update: 6 A
Update: 7 A
Update: 8 A
Update: 9 A

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

Messages postés
14605
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
12 août 2020
427
C'est justement ce que je cherche à faire entre un ordinateur et un appareil mobile (téléphone ou tablette) et donc dans mon cas les attributs peuvent être modifiés soit d'un coté ou de l'autre.
Ton code va me permettre de trouver les ajouts ce qui est déjà un bon début pour moi.
Je partirais aussi de cette méthode pour tester les mise à jours, j'ai un champ DateDeModif et un champ UniqueId pour commencer.
Messages postés
11
Date d'inscription
mercredi 15 juillet 2009
Statut
Membre
Dernière intervention
20 janvier 2012

la méthode "diffObjectToUpdate" est optionnel.
Elle peut être utilisé dans le cas de mis a jour d'une table en relation:

User
FirstName, LastName, ...
List<Contat> Contacts

les éléments de la collection "Contacts" peuvent être supprimé, ajouté ou mise à jour
Messages postés
11
Date d'inscription
mercredi 15 juillet 2009
Statut
Membre
Dernière intervention
20 janvier 2012

Bonjour whismeril,

Ce code sert avant tout à comparer deux collection qui comportent des éléments de différents types par ID (donc les attributs peuvent être différentes )

Le cas d'application :

la collection des VO (Value Objects utilisé dans les échanges client/server ajax ) est comparé à la collection des objets Entity Framework
Messages postés
14605
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
12 août 2020
427
Bonjour, je ne comprends pas le nom de diffObjectToUpdate, cette fonction retourne les éléments communs aux deux collections mais ne compare pas leur attributs.
De mon point de vue un élément à mettre à jour est un élément commun aux deux collections dont au moins un attribut est différent. Il faut ensuite discriminer laquelle des ces 2 instances sera prise en référence.

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.