Linq в DataTable - невозможно преобразовать DBNull

Новичок в Linq, извиняюсь, если это базовый вариант. Этот запрос вызывает ошибку {"Невозможно привести DBNull.Value к типу 'System.Int64'. Используйте тип, допускающий значение NULL."}, Когда я перечисляю результаты.

    private void AddLevels(long rootid)
    {
        var results = from row in data.AsEnumerable()
                      where row.Field<long>("ParentID") == rootid
                      select row;

        foreach (DataRow row in results)
        {
            //do stuff
        }

    }

Столбец ParentID принимает значения NULL - нужно ли мне обрабатывать их отдельно?

РЕДАКТИРОВАТЬ2: Фактическое решение ниже, которое по-прежнему использует Linq.

РЕДАКТИРОВАТЬ: Я решил эту проблему, отказавшись от Linq и просто используя вместо этого оператор DataTable.Select. Если у кого-то есть информация о разнице в производительности, мне было бы интересно.


person David M    schedule 17.08.2011    source источник


Ответы (2)


Используйте эту строку в своем запросе:

where row.Field<decimal?>("ParentID") == rootid

decimal? - это синтаксический сахар для System.Nullable<decimal>, который по сути совпадает с decimal, за исключением того, что он также позволяет для null значений.

long - это совсем другой тип - он может представлять только целые, а не десятичные значения, поэтому возникает ошибка «Указанное приведение недопустимо».

person Donut    schedule 17.08.2011
comment
Пончик - спасибо. Это изменило ошибку на Указанное приведение неверно. - person David M; 17.08.2011
comment
@David M - Хм, это может быть не так просто; поскольку нет неявного преобразования из DBNull в long?. - person Donut; 17.08.2011
comment
@ Дэвид, какой тип ParentID в вашей базе данных? - person Manatherin; 17.08.2011
comment
@Manatherin в DataTable - это System.Decimal; в исходной БД (Oracle) это Number (22,0). Rootid берется из столбца, не допускающего значения NULL, если это актуально? - person David M; 17.08.2011
comment
@David M Ах, это твоя проблема. Подожди, я обновлю свой ответ - person Donut; 17.08.2011
comment
@David M Обновлено - просто используйте decimal? вместо long? - person Donut; 17.08.2011
comment
@David стоит отметить с изменением пончиков, что rootid, вероятно, также должен быть десятичным типом, если он предназначен для сопоставления с этим столбцом - person Manatherin; 17.08.2011
comment
@Donut - Отлично! Помогает мне изучать C # по одному ответу StackOverflow за раз. - person David M; 17.08.2011
comment
@Manatherin - да, я тоже обновил rootid. Спасибо, что указали на это. - person David M; 17.08.2011

long rootid имеет тип, допускающий значение NULL? Это должно быть только тогда, когда он может принимать нули

person Zenwalker    schedule 17.08.2011