Solution to Error: The Data Source ‘ods_DataSource’ Does Not Support Sorting With IEnumerable Data
Suppose you have a grid view and associated datasource as ods_DataSource. The select method is defined as
DemoObject
1234
publicISingleResultSelectMethod(){//Get DAL Instance DALInstancereturnDALInstance.GetDATA(){}}
Now if you try to sort on some column the following error pops up.The data source ‘ods_DataSource’ does not support sorting with IEnumerable data. Automatic sorting is only supported with DataView, DataTable, and DataSet.This is because to implement sorting you must have datasource of type DataView/DataTable/DataSet. Now if you are using traditional 3 tier architecture and returning one of these three datatypes everything works fine. The problem arises when you are using Linq. There are two possible solution for this..
Implement custom sorting.
Change IEnumerable datatype into one of these datatypes.
Here we will try to follow 2nd approach. In our data access layer we will change IEnumerable into a DataTable using an static utility class. Here is the code to perform that operation
publicstaticclassUtil{publicstaticDataTableToDataTable(thisIEnumerablevarlist,CreateRowDelegatefn){DataTabledtReturn=newDataTable();// column namesPropertyInfo[]oProps=null;// Could add a check to verify that there is an element 0foreach(Trecinvarlist){// Use reflection to get property names, to create table, Only first time, others will followif(oProps==null){oProps=((Type)rec.GetType()).GetProperties();foreach(PropertyInfopiinoProps){// Note that we must check a nullable type else method will throw and errorTypecolType=pi.PropertyType;if((colType.IsGenericType)&&(colType.GetGenericTypeDefinition()==typeof(Nullable))){// Since all the elements have same type you can just take the first element and get typecolType=colType.GetGenericArguments()[0];}dtReturn.Columns.Add(newDataColumn(pi.Name,colType));}}DataRowdr=dtReturn.NewRow();//Iterate through each property in PropertyInfoforeach(PropertyInfopiinoProps){// Handle null values accordinglydr[pi.Name]=pi.GetValue(rec,null)==null?DBNull.Value:pi.GetValue(rec,null);}dtReturn.Rows.Add(dr);}return(dtReturn);}publicdelegateobject[]CreateRowDelegate(Tt);}ChangesintheSelectmethodpublicISingleResultSelectMethod(){//Get DAL Instance DALInstancereturnDALInstance.GetSomeData(){}}publicDataTableGetSomeData(){ISingleresult=//code to get result;return(result.ToDataTable(rec=>newobject[]{result}));}
As you can see ToDataTable is an extenstion method and will be available to all IEnumerable types.Obviously there are some performance overhead due to use of reflection but still this approach can be used. However for real time applications performance testing must be performed.