1

我正在使用一个现有的对象框架,该框架使用特殊值来表示基元 int、DateTime、long 的 NULL。包含这些值的数据将添加到 DataTable 并显示在第三方控件(例如 XtraGrid)中。

一切都很好,除非将聚合应用于数据。在这种情况下,显然处理的是特殊值而不是 NULL 条目。

所以我认为最好的解决方案是在放入 DataRow 时将值映射到 DBNull 或从 DBNull 映射。我考虑过对 DataTable 和 DataRow 进行子类化,但基类不允许覆盖访问器。

我可以向子类添加额外的 Get/Set 函数,但这依赖于记住使用它们。我可以添加静态辅助函数而不是子类化,但这有同样的问题。

有没有更优雅的解决方案?

更新 执行聚合的是网格本身,因为它具有灵活的控件,可以让用户在运行时定义摘要。所以我认为唯一真正的解决方案是以某种方式映射到/从 DBNull,只是寻找一种优雅的方式来做到这一点。

4

2 回答 2

1

您可以创建一个扩展方法来帮助您填充数据表并将值转换为 dbnull:

public static class DataExtensions
{
    public static DataRow AddRow(this DataRowCollection rowCollection, params object[] values)
    {
        object[] newValues = new object[values.Length];

        for(int i=0;i<values.Length;i++)
        {
            object value = values[i];
            if (value != null)
            {                    
                Type t = value.GetType();
                //check for min value only for value types...
                if (t.IsValueType)
                {
                    //maybe you can do some caching for that...
                    FieldInfo info = t.GetField("MinValue",
                        System.Reflection.BindingFlags.Static
                        | System.Reflection.BindingFlags.Public
                        );
                    if (info != null)
                    {
                        object o = info.GetValue(null);
                        if (value.Equals(o))  //very important == will return false
                        {
                            value = DBNull.Value;
                        }
                    }
                }
            }
            newValues[i] = value;               
        }

        return rowCollection.Add(newValues);
    }
}

然后您将能够编写如下内容:

t.Rows.AddRow(a,b,c,d,e);
于 2009-12-16T09:25:56.417 回答
0

也许您可以使用 IIF 创建条件聚合,例如(愚蠢的示例):

        DataTable t= new DataTable();
        t.Columns.Add("id");
        t.Columns.Add("id2");
        t.Columns.Add("id3", typeof(int), "IIF(id="+int.MinValue.ToString()+",id2,id+id2)");
        for (int i = 0; i < 5; i++)
        {
            t.Rows.Add(new object[] { i, 2 * i });
        }

        t.Rows.Add(new object[] { int.MinValue, 2000});

编辑:适应您对其他帖子的评论。

于 2009-12-15T14:28:19.913 回答