views:

804

answers:

2

I have a data table and I want to perform a case insensitive group by over a column of data table (say Column1 of type string). I observed that normally LINQ to DataSet perform case sensitive comparison. For example if Column1 is having two values say Test and test, after applying group by it returns two seperate rows with values Test and test. The query is as follows:

var countGroupQuery = from table in dataTable.AsEnumerable()
                      group table by table.Field<string>(Column1) into groupedTable
                      select new
                      {
                          value = groupedTable.Key,
                          count = groupedTable.Count()
                      };

so, is there any method exist to perform case in-sensitive group by so that in above example I get only one row with one value either Test or test? Also I dont want to use ToUpper or ToLower methods because it actually changes the values to either upper case or lower case.

group table by table.Field<string>(Column1).ToUpper() into groupedTable

Thanks,

+2  A: 

This MSDN article has some information on datasets and case sensitivity..

You can control the case sensitivity of filtering, searching, and sorting by setting the dataset's CaseSensitive property.

Quintin Robinson
In my case DataTable is independent of Dataset so case sensitive property is set to false. I think Linq doesnt refer to this property.It is for the operations exposed by Dataset/Datatable class.
Anoop
DataTable also has the property. But honestly I haven't used LINQ to interact with datasets/tables so I can't say whether it would actually have an effect.
Quintin Robinson
+6  A: 

You can't do this from a query expression, but you can do it with dot notation:

var query = dataTable.AsEnumerable()
                     .GroupBy(x => table.Field<string>(Column1),
                              StringComparer.InvariantCultureIgnoreCase)
                     .Select(groupedTable => new
                             {
                                 value = groupedTable.Key,
                                 count = groupedTable.Count()
                             });

You can even use a more complicated overload of GroupBy to do it in one call:

var query = dataTable.AsEnumerable()
                     .GroupBy(x => table.Field<string>(Column1),
                              (key, group) => { value = key, 
                                                count = group.Count() },
                              StringComparer.InvariantCultureIgnoreCase));

Obviously that's using the invariant culture - you could also use the current culture or ordinal rules.

Jon Skeet
Thanx for the answer. this is what I am looking for!!!By the way if i want to apply group by on more than one column(Column1 and Column2) then how should this query look like??
Anoop
@Anoop: Grouping by more than one column *and* doing so in a case-insensitive manner will be tricky. You'd probably be best off building a custom type containing the columns you're interested in, and overriding Equals.
Jon Skeet
Jon! Can you please explain it in a little more detailed manner??
Anoop
I'm afraid I don't have time at the moment. I'll try to come back to this later on.
Jon Skeet