DateTime2 в C# DateTime с помощью SqlDataReader
Я понимаю, что это может быть обманом, но я потратил часы на поиски ответа и, кажется, не могу его найти.
В настоящее время я создаю веб-API, который извлекает концертные данные.
У меня есть таблица SQL Server, которая содержит начальную и конечную даты, как Тип datetime2
. Я вставил даты в этот формат, и они не вызывают никаких проблем при просмотре базы данных:
2015-10-08T20:00:00.0000000+01:00
Моя модель:
public class Concert
{
public int Id { get; set; }
public string Name { get; set; }
public int LocationId { get; set; }
[Column(TypeName = "DateTime2")]
public DateTime Start { get; set; }
[Column(TypeName = "DateTime2")]
public DateTime End { get; set; }
public string Description { get; set; }
public string Url { get; set; }
}
И мой метод в классе, который выводит мою базу данных данные:
public List<Concert> getAll()
{
List<Concert> concerts = new List<Concert>();
SqlConnection connection = CasWebAPIdb.getConnection();
String selectAll = "SELECT ConcertId, ConcertName, ConcertLocationId FROM dbo.Concerts";
SqlCommand selectCommand = new SqlCommand(selectAll, connection);
try
{
connection.Open();
SqlDataReader reader = selectCommand.ExecuteReader();
var isoDateTimeFormat = CultureInfo.InvariantCulture.DateTimeFormat;
while (reader.Read())
{
//Debug.WriteLine("lol: " + reader["ConcertEnd"].GetType());
Concert concert = new Concert();
concert.Id = (int)reader["ConcertId"];
concert.Name = reader["ConcertName"].ToString();
concert.LocationId = (int)reader["ConcertLocationId"];
concert.Start = (DateTime)reader["ConcertStart"];
concert.End = (DateTime)reader["ConcertEnd"];
concerts.Add(concert);
}
}
catch (SqlException ex)
{
throw ex;
}
finally
{
connection.Close();
}
return concerts;
}
}
Я получаю эту ошибку при отладке:
Исключение типа ' System.IndexOutOfRangeException ' произошло в системе.Данные.dll, но не был обработан в пользовательском коде
Я перепробовал много вещей и следовал многим примерам и кодам, но я, кажется, не могу преобразовать это должным образом. У кого-нибудь есть идея?
Решение
Я забыл добавить "concertStart" и "concertEnd" к моему запросу. Проблема решена, спасибо!
3 ответа:
Прежде всего, если вы хотите прочитать значение
ConcertStart
иConcertEnd
, вам придется включить их в свойSELECT
!!$string selectAll = @"SELECT ConcertId, ConcertName, ConcertLocationId, ConcertStart, ConcertEnd <<--- add these!! FROM dbo.Concerts";
Попробуйте это:
while (reader.Read()) { Concert concert = new Concert(); concert.Id = (int)reader["ConcertId"]; concert.Name = reader["ConcertName"].ToString(); concert.LocationId = (int)reader["ConcertLocationId"]; concert.Start = reader.GetFieldValue<DateTime>(reader.GetOrdinal("ConcertStart")); concert.End = reader.GetFieldValue<DateTime>(reader.GetOrdinal("ConcertEnd")); concerts.Add(concert); }
У меня нет никаких проблем вообще считывание значения
DATETIME2(3)
из базы данных SQL Server с помощьюreader.GetFieldValue<DateTime>(reader.GetOrdinal("ConcertEnd"));
Это работает для вас?
Проблема в том, что при выборе вы возвращаете только 3 из необходимых столбцов:
String selectAll = "SELECT ConcertId, ConcertName, ConcertLocationId ...";
В то время как в вашем читателе вы пытаетесь выскрести 5 столбцов:
concert.Id = (int)reader["ConcertId"]; concert.Name = reader["ConcertName"].ToString(); concert.LocationId = (int)reader["ConcertLocationId"]; concert.Start = (DateTime)reader["ConcertStart"]; concert.End = (DateTime)reader["ConcertEnd"];
Отсюда и
IndexOutOfRangeException
. Либо выделите все столбцы, либо удалите посторонние из считывателя.Вопрос не относится к SQL
DateTime2
против .ЧистаяDateTime
- ADO будет выполнить привязку этих просто отлично.
Я бы сделал это с помощью метода расширения, который я нашел здесь
public static DateTime ToDate(this string input, bool throwExceptionIfFailed = false) { DateTime result; var valid = DateTime.TryParse(input, out result); if (!valid) if (throwExceptionIfFailed) throw new FormatException(string.Format("'{0}' cannot be converted as DateTime", input)); return result; }
Преобразуйте данные следующим образом:
concert.Start = reader["ConcertStart"].ToString().ToDate(); concert.End = reader["ConcertEnd"].ToString().ToDate(true); //throws an exception if it fails
Надеюсь, это поможет!