2012-08-24 49 views
1

我正在使用c#動態Linq庫來編寫針對數據表的自定義查詢。我遇到的問題是,當我試圖對具有空值的字段執行彙總操作時,出現錯誤。動態Linq到Datatable可空字段

我試圖執行類似的查詢:

var query = myDataTable.AsEnumerable().AsQueryable(); 

var newquery = query.GroupBy("new (get_item(@0).ToString() AS Forename)", "it", groupList.ToArray()); 

newquery = newquery.Select("new (it.Key.Tier.ToString() as Tier, @0(it) as SumTotal", funcs.ToArray()); 

如果有我總結的列具有空值然後我得到一個錯誤「無法施展DBNull.Value鍵入‘System.Double’ 。請使用可空類型。「

funcs數組包含一個lambda表達式來執行Sum函數。它是通過調用以下函數構建的。

public LambdaExpression GetGroupByLambdaExpression(Type groupByKeyType, string columnName, Type columnType, string expType) 
    { 
     ConstantExpression colParam = Expression.Constant(columnName, typeof(string)); 

     MethodInfo fieldMethod = typeof(DataRowExtensions).GetMethod("Field", new Type[] {typeof(DataRow), typeof(string)}); 
     fieldMethod = fieldMethod.MakeGenericMethod(columnType); 
     ParameterExpression rowParam = Expression.Parameter(typeof(DataRow), "r"); 

     MethodCallExpression fieldMethodCall = Expression.Call(fieldMethod, rowParam, colParam); 
     dynamic columnExpression = Expression.Lambda(fieldMethodCall, rowParam); 

     MethodInfo sumMethod = null; 
     if (expType == "Count") 
     { 
      //Count will return 2 methods, we only want the first one with 1 parameter 
      sumMethod = typeof(Enumerable).GetMethods().Single(m => m.Name == expType & m.ReturnType.Equals(columnType) & m.IsGenericMethod & m.GetParameters().Count() == 1); 
     } 
     else if (expType == "Average") 
     { 
      //Average has multiple overrides so just use the first one     
      if (columnType == typeof(Int16) || columnType == typeof(Int32) || columnType == typeof(Int64)) 
      { 
       sumMethod = typeof(Enumerable).GetMethods().First(m => m.Name == expType & m.ReturnType.Equals(typeof(double)) & m.IsGenericMethod); 
      } 
      else 
      { 
       sumMethod = typeof(Enumerable).GetMethods().First(m => m.Name == expType & m.ReturnType.Equals(columnType) & m.IsGenericMethod); 
      } 
     } 
     else 
     { 
      sumMethod = typeof(Enumerable).GetMethods().Single(m => m.Name == expType & m.ReturnType.Equals(columnType) & m.IsGenericMethod); 
     } 

     sumMethod = sumMethod.MakeGenericMethod(typeof(DataRow)); 

     ParameterExpression groupParam = Expression.Parameter(groupByKeyType, "g"); 

     MethodCallExpression sumMethodCall = null; 
     if (expType == "Count") 
     { 
      sumMethodCall = Expression.Call(sumMethod, groupParam); 
     } 
     else 
     { 
      sumMethodCall = Expression.Call(sumMethod, groupParam, columnExpression);    
     } 

     dynamic sumALambda = Expression.Lambda(sumMethodCall, groupParam); 

     return sumALambda; 
    } 

有沒有人有任何想法如何處理數據表上的DbNull值?我完全難倒了

回答

0

實際上,答案是用lambda表達式的構建中的可空對等替換DataTable列數據類型。

0

是否有什麼理由不能在開始查詢之前過濾數據表?

var query = myDataTable.Where(val => !Convert.IsDbNull(val)).AsEnumerable().AsQueryable(); 
+0

在我真正的應用程序中,我正在做多個摘要,所以在每個摘要字段上過濾null值將刪除我不想刪除的數據。 – keitn