Union is one of the set query operators available in linq. It appends 2 input sequences together ensuring that duplicates are removed and returns a single output sequence. The prototype for union operator looks like this
public static IEnumerable<T> Union<T>(
this IEnumerable<T> first,
Union operator is an extension method that is available on any object that implements IEnumerable<T>. Union operator performs the same function as concat operator with a difference that it gets rids of the duplicates elements in both the sequence. It enumerates the first sequence making sure it is not returning an element that has not been previously returned. It then iterates through the second sequence making sure that it is outputting any element that has been previously returned. Union operator uses GetHashCode and Equals method to determine if two elements are same. Let's look at some examples of union operator
The above example is pretty simple. All I am doing is simply joining two sequences into one output sequence. If we modify the example where we have duplicates we will notice that union operator will ensure that it would not repeat duplicate items in the output sequence. Here is an example of that.
The above example has duplicates with in the collection as well duplicates between the 2 collections. When we apply the union operator, we get rid of duplicates and end up with distinct elements from both the sequence as shown in the output results below.
So far we have looked at examples for union with linq to objects, union operator can also be applied to linq to SQL and Linq provider converts the union linq operator into union operator in SQL server. Let's run through an example of using union operator in linq to SQL.
In the above example we are making use of Union operator in linq to SQL because IQueryable Provider also defines the implementation of union operator, hence the linq query gets converted into SQL syntax that SQL server can understand. In the example above we are create our first collection by taking the first 50 orders and traversing its Customer relationship to access its companyname. We then union it with a second collection that we create by getting the next 50 orders and traversing its customer property to get to its companyname. Since a customer may have many orders we can without any doubt assume companyname in both the collection has been repeated several times but once we apply the union operator we end up with only 39 unique companynames between total order of 100 as shown in the output screen.
Union operator is one of those query operators which does not have any direct translation in query syntax. Therefore if you want to make use of union operator you have to resort to method or dot syntax as we have been using through out this example.
So far we have looked at examples that made use of union operator in linq to objects and linq to SQL. We can also use union operator with linq to XML. Let's look at an example of that.
In the above example, we make use of union operator with linq to XML. I create my first collection by calling descendants on the XML document to grab all the name elements from it and than I take the first 3 names elements from it. Next I apply the union operator to join it to my second collection which consists of all names elements except the first 3. However if you look at the output results, you would notice that we still have duplicates in our results. The reason for this is, Xelement is a complex object type and the way query engine determines if two nodes are equal is by making use of GetHashCode and Equals method. Since Xelement is a reference type, the results are not the same. In a situation like the above, we can use the overloaded version union operator that allows us to pass our own EqualityComparer object in which we can define how two nodes are considered equal. Let's have a look at an example.
In the example above I have created a class called NodeComparer which implements IEqualityComparer and defines the appropriate implementation of how two nodes can be compared. Secondly I am using an overloaded version of the Union operator that allows me to pass in my custom comparer which in this case i am passing an instance of NodeComparer. As you can see from the output, our results are unique and consists of names that are not repeated.