【问题标题】:Dynamic Linq to Datatable Nullable Fields动态 Linq 到数据表可为空的字段
【发布时间】:2012-08-20 01:42:54
【问题描述】:

我正在使用 c# Dynamic Linq 库来编写针对数据表的自定义查询。我遇到的问题是,当我尝试对具有空值的字段执行汇总操作时,我遇到了错误。

我正在尝试执行类似于以下内容的查询:

 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());

如果我求和的列有 Null 值,那么我会收到错误消息“无法将 DBNull.Value 转换为类型 'System.Double'。请使用可为空的类型。”

funcs 数组包含一个用于执行 Sum 函数的 lambda 表达式。它是通过调用下面的函数来构建的。

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 值吗?我完全被难住了

【问题讨论】:

    标签: c# linq dynamic datatable dbnull


    【解决方案1】:

    有什么理由不能在开始查询之前过滤数据表吗?

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

    【讨论】:

    • 在我的实际应用程序中,我正在执行多个摘要,因此在每个摘要字段上过滤 null 会删除我不想删除的数据。
    【解决方案2】:

    实际上,答案是在构建 lambda 表达式时将 DataTable 列数据类型替换为可以为空的等价物。

    【讨论】:

      猜你喜欢
      • 2023-03-23
      • 1970-01-01
      • 1970-01-01
      • 2013-06-28
      • 2012-06-05
      • 1970-01-01
      • 1970-01-01
      • 2013-03-15
      • 1970-01-01
      相关资源
      最近更新 更多