Wednesday, October 9, 2013

Linq to object Right outer join

I have written following linq query yet I am not getting expected result.My Expected result is all the matching record bettween lst & list & all the non matching record from list
for example.

I want following result

a,b,c,d,e,f

public class Com : IEqualityComparer<DuplicateData>    {        public bool Equals(DuplicateData x, DuplicateData y)        {            return x.address.Equals(y.address);        }        public int GetHashCode(DuplicateData obj)        {            return obj.address.GetHashCode();        }    }static void Run (){    List<string> lst = new List<string>();    lst.Add("a");    lst.Add("b");    lst.Add("c");    lst.Add("p");    List<DuplicateData> list = new List<DuplicateData>()    {        new DuplicateData{address="a"},        new DuplicateData{address="a"},        new DuplicateData{address="a"},        new DuplicateData{address="b"},        new DuplicateData{address="b"},        new DuplicateData{address="c"},        new DuplicateData{address="d"},        new DuplicateData{address="e"},        new DuplicateData{address="f"},    };    var dup = list.Distinct(new Com());    var RightJoin = from x in dup                    join y in lst                    on x.address equals y                    into right                    from z in right                    select new                    {                        UniqueAddress = z,                    };}

Try it like this:

var RightJoin = from x in dup                join y in lst                on x.address equals y                into right                from z in right.DefaultIfEmpty(x.address)                select new                {                    UniqueAddress = z,                };

result is (a,b,c,d,e,f)

Working sample: http://ideone.com/MOIhZH


Explanation

To make a left/right join in linq you have to use DefaultIfEmpty method, that will yield (default) result when there is no match (the joined result is empty). However, default value for string is null so you have to provide default value from the “left side” collection to see it in the result set.


Alternative approach

This is probably more convenient approach. Instead of selecting from z & providing the default value, you will select from x.address – the left side of the join.

var RightJoin = from x in dup                join y in lst                on x.address equals y                into right                from z in right.DefaultIfEmpty()                select new                {                    UniqueAddress = x.address,                };

No comments:

Post a Comment