none
Linq. Query RRS feed

  • Question

  • Hello,

    I have two Lists:


     A = {ID, Name} = { (Null, John), (Null, Mary), (Null, Andrew), (Null, Peter) }

     

     B = {ID, Name} = { (1, John), (2, Robert), (3, Angela), (4, Andrew) }


    I want to find which items in A do not exist in B then:


    1. Add the items to B and using an ID from the function GetID(). B would become:

        B = {ID, Name} = { (1, John), (2, Robert), (3, Angela), (4, Andrew), (231, Mary), (45, Peter)  }


    2. Then update the A list, or create a new one (C), to get the created items:

        C = {ID, Name} = { (231, Mary), (45, Peter) }


    How can I do this with LINQ?


    I have been trying a join but with the something as "not equals" but it does not work.


    I think I might need to do this in 3 steps:


    1. Get items in B that do not exist in C;
    2. Insert those items in C;
    3. Get those items again from C to get the created ID's with the correspondent names.


    Could someone help me out with this?


    Thanks,
    Miguel
    Friday, July 4, 2008 1:43 PM

Answers

  • You can use the Except LINQ operator to find the list of items in A that are not in B.  Though to do the kind of comparison you want you'll have to come up with an IEqualityComparer to feed into the Except method.  I've made a LINQ extension for you that will allow you to simply specify lambda expressions where necessary.

     

        public static class MoreLINQ

        {

            public static IEnumerable<T> Except<T>(this IEnumerable<T> first, IEnumerable<T> second, Func<T, T, bool> comparer)

            {

                return first.Except(second, new FuncComparer<T>(comparer, null));

            }

     

            public static IEnumerable<T> Except<T>(this IEnumerable<T> first, IEnumerable<T> second, Func<T, T, bool> comparer, Func<T, int> hasher)

            {

                return first.Except(second, new FuncComparer<T>(comparer, hasher));

            }

     

            class FuncComparer<T> : IEqualityComparer<T>

            {

                Func<T, T, bool> comparer;

                Func<T, int> hasher;

                internal FuncComparer(Func<T, T, bool> comparer, Func<T, int> hasher)

                {

                    this.comparer = comparer;

                    this.hasher = hasher;

                }

                public bool Equals(T x, T y)

                {

                    return this.comparer(x, y);

                }

     

                public int GetHashCode(T obj)

                {

                    if (hasher == null) return 0;

                    return this.hasher(obj);

                }

            }

        }

     

        class Program

        {

            class Person

            {

                public int? Id { get; private set; }

                public string Name { get; private set; }

                public Person(int? id, string name) { this.Id = id; this.Name = name; }

            }

     

            static void Main(string[] args)

            {

                var a = new[] { new Person(null, "John"), new Person(null, "Mary"), new Person(null, "Andrew"), new Person(null, "Peter") };

                var b = new[] { new Person(1, "John"), new Person(2, "Robert"), new Person(3, "Angela"), new Person(4, "Andrew") };

     

                var c = a.Except(b, (x, y) => x.Name == y.Name);

     

                Console.WriteLine("Items not in 'b'");

                foreach (var item in c)

                {

                    Console.WriteLine(item.Name);

                }

                Console.ReadLine();

            }

        }

    Friday, July 4, 2008 4:12 PM
    Moderator