Приведение нулевого значения DateTime из базы данных?

#c# #sql-server #datetime #casting

#c# #sql-сервер #datetime #Кастинг

Вопрос:

Я выполняю простую инструкцию SELECT и пытаюсь вернуть значение из столбца DateTime из таблицы SQL Server 2012. Проблема в том, что когда я возвращаю нулевое значение DateTime, я не знаю, как управлять этим с помощью моего кода ниже.

 dtTrainingEnd = (DateTime)reader["TrainingEnd"];
  

Последние несколько дней я искал ответ и не могу найти что-то, что мне поможет. Я нашел похожие сообщения, но все еще не могу понять, как они могут мне помочь. Не могли бы вы, пожалуйста, объяснить, как я могу проверить, является ли значение datetime, возвращаемое из базы данных, нулевым?

 SqlConnection connRead = new SqlConnection(connReadString);
SqlCommand comm = new SqlCommand();
SqlDataReader reader;
string sql;

DateTime dtTrainingEnd = DateTime.Now;
int iTrainingSwipeID = 123;

sql = "SELECT TrainingEnd FROM TrainingSwipe WHERE TrainingSwipeID = "   iTrainingSwipeID;

comm.CommandText = sql;
comm.CommandType = CommandType.Text;
comm.Connection = connRead;

connRead.Open();
reader = comm.ExecuteReader();

while (reader.Read())
{
    dtTrainingEnd = (DateTime)reader["TrainingEnd"];
}
connRead.Close();
  

Комментарии:

1. Примечание к типу DateTime, DateTime — это тип значения (struct), при извлечении значения null оно само устанавливает значение по умолчанию. Значение по умолчанию этого типа равно ’01/01/0001′.

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

Ответ №1:

Если это возможно null , вы могли бы использовать тип с нулевым значением … в данном случае DateTime? тип:

 while (reader.Read())
{
    dtTrainingEnd = ((DateTime?)reader["TrainingEnd"]) ?? some_default_date;
}
connRead.Close();
  

Или просто протестируйте null , если вы предпочитаете это делать:

 while (reader.Read())
{
    var endDate = reader["TrainingEnd"];
    dtTrainingEnd = (endDate == null) ? some_default_date : (DateTime)endDate;
}
connRead.Close();
  

В обоих случаях выше, я предположил, что вы хотите, dtTrainingEnd чтобы содержать что-то , если дата имеет значение null в базе данных, поэтому some_default_date некоторые даты и времени по умолчанию.

Или, если вы хотите оставить dtTrainingEnd в покое, если значение равно NULL, то просто не устанавливайте его в этом случае:

 while (reader.Read())
{
    if ((reader["TrainingEnd"]) != null)
        dtTrainingEnd = (DateTime)reader["TrainingEnd"];
}
connRead.Close();
  

*** В зависимости от способа подключения к вашей базе данных, возможно, придется заменить null на DBNull.Value

Комментарии:

1. более широким шаблоном мог бы быть reader["field"] as DateTime? ?? some_default_date ; это будет полезно для обработки того же сценария с таблицами данных, как null становится DBNull.Value

2. @Grant, во втором примере, что будет сохранено в dtTrainingEnd, если значение базы данных равно NULL? Другими словами, каким будет оператор if, чтобы увидеть, является ли datetime нулевым или нет? Извините, я совершенно не разбираюсь в этой теме.

3. @Grant, хорошо, я думаю, я понял. Большое вам спасибо за ваше терпение и помощь. 😀

4. @Grant, когда я ввожу код, я получаю сообщение об ошибке «System. Исключение IndexOutOfRangeException: завершение обучения» для оператора if «if ((reader[«Завершение обучения»]) != null)». Есть идеи? Я не могу поверить, что в c # так сложно определить, является ли datetime нулевым … : (

5. @Grant, по какой-то причине для меня проверка «== null» возвращала not null для всех записей из базы данных, которые не были null. Итак, небольшой поиск нашел это для меня «== DBNull. Значение «сделало свое дело. Не уверен, в чем разница, но я подумал, что упомяну об этом на случай, если у кого-то еще возникнет такая же проблема.

Ответ №2:

С помощью SQL вы можете выполнить SELECT Coalesce(TrainingEnd,0), и если оно равно null, у вас будет дата 1900-01-01…