Linq. Query

Last post 07-09-2009 3:41 PM by tkraft. 4 replies.

Sort Posts:

  • Linq. Query

    07-04-2008, 9:41 AM
    • Contributor
      3,569 point Contributor
    • shapper
    • Member since 11-28-2004, 9:15 PM
    • Posts 2,947

     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
  • Re: Linq. Query

    07-04-2008, 10:58 AM
    Answer
    • All-Star
      20,998 point All-Star
    • Jeev
    • Member since 11-24-2005, 12:49 PM
    • Posts 3,163

     Well See the example below. Key is that you  have to have an IEqualityComparer implemented

    1     static void Main(string[] args)
    2            {
    3    
    4                List A = new List { new Test { ID = 1, Name = "John" }, new Test { ID = 2, Name = "Mary" }, 
    5                    new Test { ID = 3, Name = "Andrew" },new Test {ID=4,Name="Peter"} };
    6                List B = new List { new Test { ID = 1, Name = "John" }, new Test { ID = 21, Name = "Robert" }, 
    7                    new Test { ID = 9, Name = "Angela" },new Test {ID=3,Name="Andrew"} };
    8          
    9                var ItemsinAThatDoNotExistinB = A.Except(B,new TestComparer()).ToList();
    10           }
    11   
    12   public class TestComparer : IEqualityComparer
    13       {
    14           #region IEqualityComparer Members
    15   
    16           public bool Equals(Test x, Test y)
    17           {
    18               if (x.Equals(y))
    19               {
    20                   return true;
    21               }
    22               else
    23               {
    24                   return false;
    25               }
    26           }
    27   
    28           public int GetHashCode(Test obj)
    29           {
    30               return obj.ToString().ToLower().GetHashCode();
    31   
    32           }
    33   
    34           #endregion
    35       }
    36       public class Test:IEquatable
    37       {
    38           public int? ID {get;set;}
    39           public string Name { get; set; }
    40   
    41           #region IEquatable Members
    42   
    43          
    44   
    45           public bool Equals(Test other)
    46           {
    47               if (this.ID == other.ID  && this.Name.Equals(other.Name))
    48               {
    49                   return true;
    50               }
    51               else
    52               {
    53                   return false;
    54               }
    55           }
    56   
    57           #endregion
    58   
    59           
    60       }
    
      
    Jeev
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    If you get the answer to your question, please mark it as the answer.
  • Re: Linq. Query

    07-04-2008, 11:11 AM
    • Contributor
      2,766 point Contributor
    • RichardD
    • Member since 09-03-2002, 11:43 AM
    • Sussex, UK
    • Posts 364

    Assuming you have a suitable equality comparer, or have implemented IEquatable<T>, you can use the Except and Concat methods:

    1. C = A.Except(B) [or A.Except(B, comparer) to pass an equality comparer];
    2. Update the ID of all elements in C;
    3. B = B.Concat(C)
  • Re: Linq. Query

    07-06-2008, 1:56 AM
    • Contributor
      5,028 point Contributor
    • Paul Linton
    • Member since 04-30-2008, 3:16 AM
    • Posts 879

    Try this

     

    // You must have some class like this already
    public class Info {
        public int? ID {get; set;}
        public string Name {get; set;}
    }
    // Load some data so I can test
    List<Info> A = new List<Info> { new Info { Name = "John" }, new Info { Name = "Mary" }, new Info { Name = "Peter" } };
    List<Info> B = new List<Info> { new Info { ID = 1, Name = "John" }, new Info { ID = 2, Name = "Robert" }, new Info { ID = 3, Name = "Angela" }, new Info { ID = 4, Name = "Andrew" } };
    
    // Make List C
    List<Info> C = A.Select(a => new { Name = a.Name }).Except(B.Select(b => new { Name = b.Name })).Select(c => new Info { ID = GetID(c.Name), Name = c.Name }).ToList();
    // Append C to B
    B = B.Union(C).ToList();
    
    To create list C you need to make an IEnumerable with just the Name field, this is what the Select(a=> new {Name = a.Name}) does.  The Except query operator is one way to do the 'not equals' join.  Then create a new IEnumerable<Info> using GetID and the Names.
    Appending C to B is just the Union query operator.
    Hope this helps
    Got a c# problem? Try .NET Book Zero from Charles Petzold, it's a free pdf.
  • Re: Linq. Query

    07-09-2009, 3:41 PM
    • Member
      35 point Member
    • tkraft
    • Member since 08-27-2004, 10:32 AM
    • Indiana
    • Posts 13

    If anyone wanders in here...

    the public class TestComparer : IEqualityComparer  needs to have the type specified:

    public class TestComparer : IEqualityComparer<Test>

    Toby
Page 1 of 1 (5 items)