LINQ Distinct, a DataTable and the IEqualityComparer<T>

by Ira 26. August 2008 17:58

In a recent situation I was trying to pull some aggregates out of a DataTable using LINQ. I needed to get the rows of the DataTable with a Distinct clause, but my aggregates would be on other columns of the row. The problem is that when you call LINQ's Distinct() extension method with no arguments, it uses the "default IEqualityComparer". This means that it will work if you use the Select() extension method, only returning the column you want the distinct on. Well that works great, unless you need more columns from the DataTable.

 

The solution here is simple. Write a custom DataRow comparer that compares the DataRow against the column you are trying to put the distinct on. Here is an example:

 

public class PersonDataRowComparer : IEqualityComparer<DataRow>
{

 

    #region IEqualityComparer<DataRow> Members
 
    public bool Equals(DataRow x, DataRow y)
    {
        return (x.Field<int>("PersonID") == y.Field<int>("PersonID"));
    }
 
    public int GetHashCode(DataRow obj)
    {
        return obj.ToString().GetHashCode();
    }
 
    #endregion
}

 

Once we inherit IEqualityComparer<T> (T being the type we want to do the comparison on) all we do is fill in the Equals() and the GetHashCode() methods. In the Equals() method, we just tell the DataRows to compare the fields "PersonID" and return if they are equal. This will tell LINQ if the DataRow is distinct or not.

 

Hope this helps!

 

Download the code: LINQ Distinct Sample

kick it on DotNetKicks.com

 

Tags: ,

C# | LINQ

Comments

11/17/2008 9:24:44 AM #

Karogyoker

Thanks, it helped a LOT!

Karogyoker Hungary

11/27/2008 9:35:04 AM #

zhuibobo

thanks,^_^

zhuibobo People's Republic of China

12/11/2008 8:37:05 PM #

shiyunfei

非常好,不错的文章。顶

shiyunfei

6/4/2009 3:27:42 PM #

Prad

Are you not hardcoding "PERSONID" in return (x.Field<int>("PersonID") ?

Prad United States

6/4/2009 5:14:00 PM #

Ira

@Prad
Are you not hardcoding "PERSONID" in return (x.Field<int>("PersonID") ?
Yes, in this example I am. If you wanted to though, you could pass in the field name into a constructor of the PersonDataRowComparer class and make it more dynamic that way.

Ira United States

8/26/2009 12:22:34 PM #

bramoin

I am new to LinQ, is the DataRow still the correct parameter even when doing a Distinct on a List. For example, i want to do a distinct on two list of objects. List<someobjec> object1 and List<someotherobjec> object2. Can i do this: someobjec.Distinct(someotherobjec, new icomparerObj)?

bramoin United States

8/26/2009 1:01:19 PM #

bramoin

You can ignore my previous question. i figured it out. Sorry!

bramoin United States

Comments are closed

Powered by BlogEngine.NET 1.5.0.7
Theme by Mads Kristensen

About Me

IraIra
I'm just another developer from Florida.

 

Sponsors

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

All code samples on this website are free for download, use, and modification with no warranty nor any implied warranty. Liscensed by:

Creative Commons License
This work is licensed under a Creative Commons Attribution 3.0 United States License.