Linq и DBNull - Получение ошибки - PullRequest
6 голосов
/ 30 июня 2010

Я получаю сообщение об ошибке при выборе из строки. AsEnumerable ().Я использую следующий код ...

var rows = ds.Tables[0].AsEnumerable();
                trafficData = rows.Select(row => new tdDataDC
                {
                    CalculationCount = row.Field<Int64>("biCalculationCountSeqID")
                    , Zone = row.Field<Int16>("siFkZoneId")
                    , Miles = row.Field<decimal>("dcMiles")
                    , Plaza = row.Field<Int16>("siFkPlazaId")
                    , VehicleCount = row.Field<int>("iVehicleCount")


                });

Большую часть времени это работает хорошо, но когда в базе данных есть NULLS, я получаю эту ошибку "Не могу привести DBNull.Value к типу 'System.Int16 '. Пожалуйста, используйте обнуляемый тип .. "Как я могу это исправить?Я не хочу, чтобы мои контракты данных имели типы Nullable, я хотел бы использовать троичный или что-то еще, и если значение равно NULL, просто используйте 0. Это возможно?

Спасибо за любую помощь,
~ ск

Ответы [ 4 ]

11 голосов
/ 30 июня 2010

Вы всегда можете добавить другой метод расширения (непроверенный):

   public static T FieldOrDefault<T>(this DataRow row, string columnName)
   {
       return row.IsNull(columnName) ? default(T) : row.Field<T>(columnName);   
   }

Тогда ваш сайт выглядит так:

var rows = ds.Tables[0].AsEnumerable();
                trafficData = rows.Select(row => new tdDataDC
                {
                    CalculationCount = row.FieldOrDefault<Int64>("biCalculationCountSeqID")
                    , Zone = row.FieldOrDefault<Int16>("siFkZoneId")
                    , Miles = row.FieldOrDefault<decimal>("dcMiles")
                    , Plaza = row.FieldOrDefault<Int16>("siFkPlazaId")
                    , VehicleCount = row.FieldOrDefault<int>("iVehicleCount")


                });
7 голосов
/ 30 июня 2010

Вот как вы тестируете на нули ...

Plaza = row.IsNull("siFkPlazaId") ? 0 : row.Field<int>("siFkPlazaId")
4 голосов
/ 28 июля 2011

Если ваша собственность обнуляется, вы также можете сделать это;

Plaza = row.Field<int16?>("siFkPlazaId")
1 голос
/ 07 августа 2012

Мне очень нравится оператор ??:

CalculationCount = row.Field<Int64?>("biCalculationCountSeqID") ?? 0
                , Zone = row.Field<Int16?>("siFkZoneId") ?? 0
                , Miles = row.Field<decimal?>("dcMiles") ?? 0.0m
                , Plaza = row.Field<Int16?>("siFkPlazaId") ?? 0
                , VehicleCount = row.Field<int>("iVehicleCount") 0;
...