Поле набора данных DBNull -> int? - PullRequest
2 голосов
/ 02 марта 2009

SQLServer int field. Значение иногда нулевое. DataAdapter заполняет набор данных OK и может отображать данные в DatagridView OK.

При попытке получить данные программным путем из набора данных код поиска поля набора данных выдает ошибку StronglyTypedException.

 [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public int curr_reading {
        get {
            try {
                return ((int)(this[this.tableHistory.curr_readingColumn]));
            }
            catch (global::System.InvalidCastException e) {
                throw new global::System.Data.StrongTypingException("The value for column \'curr_reading\' in table \'History\' is DBNull.", e);
            }

Пройдя мимо этого, проверил DBNull в методе доступа get и вернул null, но ... Когда структура набора данных изменена (все еще развивается), мои изменения (что неудивительно) пропали.

Как лучше всего справиться с этой ситуацией? Кажется, я застрял с этим на уровне набора данных. Есть ли какой-нибудь атрибут, который может сказать авто генератору кода оставить изменения на месте?

Ответы [ 5 ]

6 голосов
/ 03 марта 2009

В конструкторе типизированных наборов данных есть свойство nullvalue. По умолчанию его значение равно throw exception (следовательно, ваш сгенерированный код) Вы можете установить его на желаемый default value .. т.е. 0. Тогда он вернет 0 вместо исключения. (генерируется другой код)

VS2008: это работает непосредственно в конструкторе наборов данных.

VS2005: он работает только для строк в конструкторе, но вы можете напрямую редактировать XSD и установить свойство msprop: nullValue = "0"

3 голосов
/ 02 марта 2009
  1. Оставьте автоматически сгенерированный код в покое. Нет никакого способа «перехватить» его создание, поэтому любые изменения, которые вы делаете, гарантированно сорвутся рано или поздно.

  2. .NET (по крайней мере, биты .NET 2.0 system.data) не будут преобразованы из DBNull во что-либо еще Это отстой, но вы ничего не можете с этим поделать.

  3. Напишите метод расширения с именем ToNullable () или аналогичный: он может сделать это:

.

public static Nullable<T> ToNullable(this object x){
    if(x == DBNull.Value)
       return default(T); // return null thing
    else
       return (T)x;
}

тогда вы можете сделать

int? thing = DataRow["column"].ToNullable<int>();
1 голос
/ 02 марта 2009

Набор данных будет иметь логическое свойство для обозначения нуля.

int curr_reading = ( Iscurr_readingColumnNull) ? 
                   <default_value> : row.curr_readingColumn;
0 голосов
/ 07 сентября 2009
if(row["curr_reading"] is DBNull){

}else{
    row.curr_reading;
}
0 голосов
/ 02 марта 2009

Если память служит, вам нужно пометить строку как отредактированную - используя .BeginEdit () или аналогичную - затем внесите изменения и сохраните строку, возможно, используя .EndEdit () или аналогичную. Возможно, вы захотите немного прочесть эти методы (они могут быть в DataSet, DataTable или DataRow) - моя память немного мутная.

Надеюсь, это поможет хоть немного.

...