tags:

views:

72

answers:

5

I'm a linq noob.... can someone please some me how to achieve this using linq... I'm trying to compare 2 lists in both directions...

    internal void UpdateUserTeams(int iUserID)
    {
        UserTeamCollection CurrentTeams = GetUserTeams(iUserID);
        UserTeamCollection UpdatedTeams = this;

        foreach (UserTeam ut in CurrentTeams)
        {
            if(!UpdatedTeams.ContainsTeam(ut.ID))
            {
                RemoveTeamFromDB();
            }
        }

        foreach (UserTeam ut in UpdatedTeams)
        {
            if (!CurrentTeams.ContainsTeam(ut.ID))
            {
                AddTeamToDB();
            }
        }

    }


    public bool ContainsTeam(int iTeamID)
    {
        return  this.Any(t => t.ID == iTeamID);
    }
A: 

You would normally use Enumerable.Except both ways to get the differences. Then add and remove as needed.

leppie
A: 
var addedTeams = UpdatedTeams.Except(CurrentTeams);
var removedTeams = CurrentTeams.Except(UpdatedTeams);
Thomas Levesque
A: 

You're trying to get the outer parts from a full outer join. Here's a rough way to achieve that.

ILookup<int, UserTeam> currentLookup = CurrentTeams
  .ToLookup(ut => ut.ID);
ILookup<int, UserTeam> updatedLookup = UpdatedTeams
  .ToLookup(ut => ut.ID);

List<int> teamIds = CurrentTeams.Select(ut => ut.ID)
  .Concat(UpdatedTeams.Select(ut => ut.ID))
  .Distinct()
  .ToList();

ILookup<string, UserTeam> results =
(
  from id in teamIds
  let inCurrent = currentLookup[id].Any()
  let inUpdated = updatedLookup[id].Any()
  let key = inCurrent && inUpdated ? "No Change" :
    inCurrent ? "Remove" :
    inUpdated ? "Add" :
    "Inconceivable"
  let teams = key == "Remove" ? currentLookup[id] :
    updatedLookup[id]
  from team in teams
  select new {Key = key, Team = team)
).ToLookup(x => x.Key, x => x.Team);

foreach(UserTeam ut in results["Remove"])
{
  RemoveTeamFromDB();
}
foreach(UserTeam ut in results["Add"])
{
  AddTeamToDB();
}
David B
+2  A: 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;    

namespace Linqage
{
    class Program
    {
        static void Main(string[] args)
        {
            UserTeamCollection currentTeams = new UserTeamCollection() 
            {
                new UserTeam(1),
                new UserTeam(2),
                new UserTeam(3),
                new UserTeam(4),
                new UserTeam(5)
            };

            UserTeamCollection updatedTeams = new UserTeamCollection()
            {
                new UserTeam(2),
                new UserTeam(4),
                new UserTeam(6),
                new UserTeam(8)                
            };

            currentTeams.Except(updatedTeams).All(u =>
            {
                //Console.WriteLine("Item ID: {0}",u.ID);
                //RemoveFromDB()
                return true;
            });

            updatedTeams.Except(currentTeams).All(u =>
            {
                //Console.WriteLine("Item ID: {0}", u.ID);
                //AddToDB()
                return true;
            });            
        }
    }

    public class UserTeamCollection
       : List<UserTeam>
    {

    }

    //Either overwrite the GetHashCode and Equals method OR create a IComparer
    public class UserTeam
    {
        public int ID { get; set; }

        public UserTeam(int id)
        {
            ID = id;
        }
        public override bool Equals(object obj)
        {
            UserTeam iOther = obj as UserTeam;
            if (iOther != null)
            {
                return this.ID == iOther.ID;
            }
            return false;
        }
        public override int GetHashCode()
        {
            return ID.GetHashCode();
        }
    }

}
andaze
A: 

So converting your initial question to an english requirement:

    foreach (UserTeam ut in CurrentTeams)           // for each current team
    {
        if(!UpdatedTeams.ContainsTeam(ut.ID))       // that is not in the updated teams list
        {
            RemoveTeamFromDB();         // remove it from the database
        }
    }

    foreach (UserTeam ut in UpdatedTeams)       //for each of the teams in the updated teams list
    {
        if (!CurrentTeams.ContainsTeam(ut.ID))  //if the current team does not contain the updated team
        {
            AddTeamToDB();              //add the team to the database
        }
    }

Therefore, you want to do:

//select all current teams that are not in updated teams list
CurrentTeam.Except(UpdatedTeams).All(team => { RemoveTeamFromDB(team); return true; });

//select all updated teams that are not in the current teams list
UpdatedTeam.Except(CurrentTeams).All(team => { AddTeamToDB(team); return true; });

Make sure your UserTeam object has proper overrides for the Equals and GetHashCode methods, so that comparison between two UserTeams is accurate :)

Blakomen