Solution to Error: data source 'ods' does not support sorting with IEnumerable data. Automatic sorting is only supported with DataView, DataTable, and DataSet.

March 21, 2008 02:32 by pradeep.mishra
Suppose you have a grid view and associated datasource as ods_DataSource.
   1:  <!-- Some other code---->
The select method is defined as
   1:   
   2:  public ISingleResult SelectMethod(){
   3:  //Get DAL Instance DALInstance
   4:  return DALInstance.GetDATA(){}
   5:  }
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..
  1. Implement custom sorting.
  2. 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
   1:   
   2:  public static class Util
   3:  {
   4:  public static DataTable ToDataTable(this IEnumerable varlist, CreateRowDelegate fn)
   5:  {
   6:  DataTable dtReturn = new DataTable();
   7:  // column names
   8:  PropertyInfo[] oProps = null;
   9:  // Could add a check to verify that there is an element 0
  10:  foreach (T rec in varlist)
  11:  {
  12:  // Use reflection to get property names, to create table, Only first time, others will follow
  13:  if (oProps == null)
  14:  {
  15:  oProps = ((Type)rec.GetType()).GetProperties();
  16:  foreach (PropertyInfo pi in oProps)
  17:  {
  18:  // Note that we must check a nullable type else method will throw and error
  19:  Type colType = pi.PropertyType; if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition() == typeof(Nullable)))
  20:  {
  21:  // Since all the elements have same type you can just take the first element and get type
  22:  colType = colType.GetGenericArguments()[0];
  23:  }
  24:  dtReturn.Columns.Add(new DataColumn(pi.Name, colType));
  25:  }
  26:  }
  27:  DataRow dr = dtReturn.NewRow();
  28:  //Iterate through each property in PropertyInfo
  29:  foreach (PropertyInfo pi in oProps)
  30:  {
  31:  // Handle null values accordingly
  32:  dr[pi.Name] = pi.GetValue(rec, null) == null ? DBNull.Value : pi.GetValue(rec, null);
  33:  }
  34:  dtReturn.Rows.Add(dr);
  35:  }
  36:  return (dtReturn);
  37:  }
  38:  public delegate object[] CreateRowDelegate(T t);
  39:  }
Changes in the Select method
   1:   
   2:  public ISingleResult SelectMethod(){
   3:  //Get DAL Instance DALInstance
   4:  return DALInstance.GetSomeData(){}
   5:  }
   6:  public DataTable GetSomeData()
   7:  {
   8:  ISingle result = //code to get result;
   9:  return (result.ToDataTable(rec => new object[] { result}));
  10:  }
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.Hope this helps!

Currently rated 3.0 by 5 people

  • Currently 3/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Comments

Add comment


(Will show your Gravatar icon)  

  Country flag

biuquote
  • Comment
  • Preview
Loading