LINQ Union Method

LINQ Union Method in C# with Examples

In this article, I am going to discuss the LINQ Union Method in C# using examples. Please read our previous article where we discussed the LINQ Intersect() Method with examples.

LINQ Union Method:

The LINQ Union Method is used to combine the multiple data sources into one data source by removing the duplicate elements. There are two overloaded versions available for the LINQ Union() Method as shown below.

LINQ Union Method in C# with Examples

Let us understand this with an example:

LINQ Union Method in C#

As shown in the above image, here we have two integer data sources i.e. DataSource 1 and Data Source 2. The DataSource 1 contains elements such as 1, 2, 3, 4, 5, 6 and the DataSource 2 contains elements such as 1, 3, 5, 8, 9, and 10. If we want to retrieve all the elements from both the collections by removing the duplicate element then we need to use the LINQ Union method.

Example1:

The following example shows the use of LINQ Union() Method using both Method and Query Syntax to fetch all the elements from both the collections by removing the duplicate elements.

using System.Collections.Generic;
using System;
using System.Linq;
namespace LINQDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            List<int> dataSource1 = new List<int>() { 1, 2, 3, 4, 5, 6 };
            List<int> dataSource2 = new List<int>() { 1, 3, 5, 8, 9, 10 };

            //Method Syntax
            var MS = dataSource1.Union(dataSource2).ToList();

            //Query Syntax
            var QS = (from num in dataSource1
                      select num)
                      .Union(dataSource2).ToList();

            foreach (var item in MS)
            {
                Console.WriteLine(item);
            }

            Console.ReadKey();
        }
    }
}

Run the application and you will see the output as expected.

Note: In query syntax, there is no such operator call Union, so here we need to use the mixed syntax i.e. using both query and method syntax.

Example2: 

Here we have two collections of countries and we need to return all the countries from both the collections by removing the duplicate country names.

using System;
using System.Linq;
namespace LINQDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] dataSource1 = { "India", "USA", "UK", "Canada", "Srilanka" };
            string[] dataSource2 = { "India", "uk", "Canada", "France", "Japan" };

            //Method Syntax
            var MS = dataSource1.Union(dataSource2).ToList();

            //Query Syntax
            var QS = (from country in dataSource1
                      select country)
                      .Union(dataSource2).ToList();

            foreach (var item in MS)
            {
                Console.WriteLine(item);
            }

            Console.ReadKey();
        }
    }
}

Now run the application and it will give us the following output.

As you can see it displays the country “UK” twice. This is because the default comparer that is being used by LINQ Union method is case-insensitive.

So if you want to ignore the case-sensitive then you need to use the other overloaded version of the Union() method which takes IEqualityComparer as an argument. So, modify the program as shown below where we pass StringComparer as an argument.

using System;
using System.Linq;
namespace LINQDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] dataSource1 = { "India", "USA", "UK", "Canada", "Srilanka" };
            string[] dataSource2 = { "India", "uk", "Canada", "France", "Japan" };

            //Method Syntax
            var MS = dataSource1.Union(dataSource2, StringComparer.OrdinalIgnoreCase).ToList();

            //Query Syntax
            var QS = (from country in dataSource1
                      select country)
                      .Union(dataSource2, StringComparer.OrdinalIgnoreCase).ToList();

            foreach (var item in MS)
            {
                Console.WriteLine(item);
            }

            Console.ReadKey();
        }
    }
}

Now run the application and it should display the data as expected as shown below

.

LINQ Union() Method with Complex Type:

The LINQ Union() Method like other Set Operators such as Distinct, Expect, Intersect is also worked in a different manner when working with complex types such as Product, Employee, Student, etc. Let us understand this with an example.

Create a class file with the name Student.cs and then copy and paste the following code in it.

namespace LINQDemo
{
    public class Student
    {
        public int ID { get; set; }
        public string Name { get; set; }
    }
}

The above student class is created with just two properties. Let say, we have the following two data sources.

LINQ Union() Method with Complex Type

As you can see in the above image, we have two collections of student data. And if you notice we have two students which are appeared in both the collections.

Example3:

Our requirement is to fetch all the student names from both the collections by removing the duplicate name.

using System.Collections.Generic;
using System;
using System.Linq;
namespace LINQDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Student> StudentCollection1 = new List<Student>()
            {
                new Student {ID = 101, Name = "Preety" },
                new Student {ID = 102, Name = "Sambit" },
                new Student {ID = 105, Name = "Hina"},
                new Student {ID = 106, Name = "Anurag"},
            };

            List<Student> StudentCollection2 = new List<Student>()
            {
                new Student {ID = 105, Name = "Hina"},
                new Student {ID = 106, Name = "Anurag"},
                new Student {ID = 107, Name = "Pranaya"},
                new Student {ID = 108, Name = "Santosh"},
            };

            //Method Syntax
            var MS = StudentCollection1.Select(x => x.Name)
                     .Union(StudentCollection2.Select(y => y.Name)).ToList();

            //Query Syntax
            var QS = (from std in StudentCollection1
                      select std.Name)
                      .Union(StudentCollection2.Select(y => y.Name)).ToList();

            foreach (var name in MS)
            {
                Console.WriteLine(name);
            }

            Console.ReadKey();
        }
    }
}

Output:

Example4:

Now we need to select all the information of all the students from both the collections by removing the duplicate students. In order to do this, let us modify the program class as shown below.

using System.Collections.Generic;
using System;
using System.Linq;
namespace LINQDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Student> StudentCollection1 = new List<Student>()
            {
                new Student {ID = 101, Name = "Preety" },
                new Student {ID = 102, Name = "Sambit" },
                new Student {ID = 105, Name = "Hina"},
                new Student {ID = 106, Name = "Anurag"},
            };

            List<Student> StudentCollection2 = new List<Student>()
            {
                new Student {ID = 105, Name = "Hina"},
                new Student {ID = 106, Name = "Anurag"},
                new Student {ID = 107, Name = "Pranaya"},
                new Student {ID = 108, Name = "Santosh"},
            };

            //Method Syntax
            var MS = StudentCollection1.Union(StudentCollection2).ToList();

            //Query Syntax
            var QS = (from std in StudentCollection1
                      select std).Union(StudentCollection2).ToList();

            foreach (var student in MS)
            {
                Console.WriteLine($" ID : {student.ID} Name : {student.Name}");
            }

            Console.ReadKey();
        }
    }
}

Once you run the application, then you will see that it display all the students without removing the duplicate students. This is because the default comparer which is used for comparison is only checked whether two object references are equal and not the individual property values of the complex object.

Let us see how to use an anonymous type to solve the above problem.

Using Anonymous Type for Union Operation in C#:

In this approach, we need to select all the individual properties to an anonymous type. The following program does exactly the same things.

using System.Collections.Generic;
using System;
using System.Linq;
namespace LINQDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Student> StudentCollection1 = new List<Student>()
            {
                new Student {ID = 101, Name = "Preety" },
                new Student {ID = 102, Name = "Sambit" },
                new Student {ID = 105, Name = "Hina"},
                new Student {ID = 106, Name = "Anurag"},
            };

            List<Student> StudentCollection2 = new List<Student>()
            {
                new Student {ID = 105, Name = "Hina"},
                new Student {ID = 106, Name = "Anurag"},
                new Student {ID = 107, Name = "Pranaya"},
                new Student {ID = 108, Name = "Santosh"},
            };

            //Method Syntax
            var MS = StudentCollection1.Select(x => new { x.ID, x.Name })
                     .Union(StudentCollection2.Select(x => new { x.ID, x.Name })).ToList();

            //Query Syntax
            var QS = (from std in StudentCollection1
                      select new { std.ID, std.Name })
                      .Union(StudentCollection2.Select(x => new { x.ID, x.Name })).ToList();
            
            foreach (var student in MS)
            {
                Console.WriteLine($" ID : {student.ID} Name : {student.Name}");
            }

            Console.ReadKey();
        }
    }
}

Now run the application and it should display the output as expected as shown below.

Let us see how to achieve the same thing using Comparer.

Using IEqualityComparer :

In this approach, we need to create a class and then we need to implement the IEqualityComparer interface. So, create a class file with the name StudentComparer.cs and then copy and paste the following code in it.

using System.Collections.Generic;
namespace LINQDemo
{
    public class StudentComparer : IEqualityComparer<Student>
    {
        public bool Equals(Student x, Student y)
        {
            return x.ID == y.ID && x.Name == y.Name;
        }

        public int GetHashCode(Student obj)
        {
            return obj.ID.GetHashCode() ^ obj.Name.GetHashCode();
        }
    }
}

Now, we need to create an instance of StudentComparer class and then we need to pass that instance to the LINQ Union method as shown in the below program.

using System.Collections.Generic;
using System;
using System.Linq;
namespace LINQDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Student> StudentCollection1 = new List<Student>()
            {
                new Student {ID = 101, Name = "Preety" },
                new Student {ID = 102, Name = "Sambit" },
                new Student {ID = 105, Name = "Hina"},
                new Student {ID = 106, Name = "Anurag"},
            };

            List<Student> StudentCollection2 = new List<Student>()
            {
                new Student {ID = 105, Name = "Hina"},
                new Student {ID = 106, Name = "Anurag"},
                new Student {ID = 107, Name = "Pranaya"},
                new Student {ID = 108, Name = "Santosh"},
            };

            StudentComparer studentComparer = new StudentComparer();

            //Method Syntax
            var MS = StudentCollection1
                     .Union(StudentCollection2, studentComparer).ToList();

            //Query Syntax
            var QS = (from std in StudentCollection1
                      select std)
                      .Union(StudentCollection2, studentComparer).ToList();

            foreach (var student in MS)
            {
                Console.WriteLine($" ID : {student.ID} Name : {student.Name}");
            }

            Console.ReadKey();
        }
    }
}

In the next article, I am going to discuss the Ordering Operators in LINQ with examples. I hope this article gives you a very good understanding of the Concept LINQ Union operation in C# with different types of examples.

Leave a Reply

Your email address will not be published. Required fields are marked *