Отображение специальных значений нулевой константы в DBNull в DataTable - PullRequest
1 голос
/ 15 декабря 2009

Я работаю с существующей объектной структурой, которая использует специальные значения для представления NULL для примитивов int, DateTime, long. Данные, содержащие эти значения, добавляются в DataTable и отображаются в сторонних элементах управления, таких как XtraGrid.

Все хорошо, кроме случаев, когда к данным применяются агрегаты. В этом случае, очевидно, специальные значения обрабатываются вместо записей NULL.

Так что я думаю, что лучшее решение - отобразить значения в / из DBNull при помещении в DataRow. Я думал о создании подклассов DataTable и DataRow, но базовые классы не позволяют переопределять методы доступа.

Я мог бы добавить дополнительные функции Get / Set к подклассам, но это полагалось на то, что они не будут использоваться. Я мог бы добавить статические вспомогательные функции вместо подклассов, но это та же проблема.

Есть ли более элегантное решение?

Обновление Агрегацию выполняет сама сетка, поскольку она имеет гибкие элементы управления, позволяющие пользователю определять итоги во время выполнения. Поэтому я думаю, что единственное реальное решение - каким-то образом отобразить в / из DBNull, просто ища элегантный способ сделать это.

Ответы [ 2 ]

1 голос
/ 16 декабря 2009

Вы можете создать метод расширения, который поможет вам заполнить таблицу данных и преобразовать значения в 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);
0 голосов
/ 15 декабря 2009

возможно, вы можете создать условные агрегаты с помощью 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});

Редактировать: адаптировано к вашему комментарию к другому сообщению.

...