使用 SqlDataReader 将 DateTime2 转换为 C# DateTime
DateTime2 to C# DateTime with SqlDataReader
我知道这可能是个骗局,但我花了几个小时寻找答案,但似乎找不到。
我目前正在创建一个网络 API 来检索音乐会数据。
我有一个 SQL 服务器 table,它包含开始日期和结束日期,两者都是 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; }
}
我在 class 中调出数据库数据的方法:
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;
}
}
调试时出现此错误:
An exception of type 'System.IndexOutOfRangeException' occurred in System.Data.dll but was not handled in user code
我已经尝试了很多东西并遵循了很多示例和代码,但我似乎无法正确转换它。有人有想法吗?
解决方案
我忘记将 'concertStart' 和 'concertEnd' 添加到我的查询中。
问题已解决,谢谢!
我会用我发现的扩展方法来做 here
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
希望对您有所帮助!
首先,如果您想读取 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);
}
我完全没有问题使用
从SQL服务器数据库读取DATETIME2(3)
值
reader.GetFieldValue<DateTime>(reader.GetOrdinal("ConcertEnd"));
这对你有用吗?
问题是在您的 select 中,您只需要 return 3 列:
String selectAll = "SELECT ConcertId, ConcertName, ConcertLocationId ...";
而在您的 reader 中,您尝试抓取 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
。 select 所有列,或者从 reader.
中删除无关的列
此问题与 Sql DateTime2
与 .Net DateTime
无关 - ADO 将很好地绑定它们。
任何想要将 SQL DateTime2 正确恢复为 DateTime 的人,包括 'Kind=Utc'
(DateTime)reader["ConcertEnd"].ToUniversalTime();
否则 DateTime 可能很难确定日期来自哪个时区
我知道这可能是个骗局,但我花了几个小时寻找答案,但似乎找不到。
我目前正在创建一个网络 API 来检索音乐会数据。
我有一个 SQL 服务器 table,它包含开始日期和结束日期,两者都是 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; }
}
我在 class 中调出数据库数据的方法:
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;
}
}
调试时出现此错误:
An exception of type 'System.IndexOutOfRangeException' occurred in System.Data.dll but was not handled in user code
我已经尝试了很多东西并遵循了很多示例和代码,但我似乎无法正确转换它。有人有想法吗?
解决方案
我忘记将 'concertStart' 和 'concertEnd' 添加到我的查询中。 问题已解决,谢谢!
我会用我发现的扩展方法来做 here
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
希望对您有所帮助!
首先,如果您想读取 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);
}
我完全没有问题使用
从SQL服务器数据库读取DATETIME2(3)
值
reader.GetFieldValue<DateTime>(reader.GetOrdinal("ConcertEnd"));
这对你有用吗?
问题是在您的 select 中,您只需要 return 3 列:
String selectAll = "SELECT ConcertId, ConcertName, ConcertLocationId ...";
而在您的 reader 中,您尝试抓取 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
。 select 所有列,或者从 reader.
此问题与 Sql DateTime2
与 .Net DateTime
无关 - ADO 将很好地绑定它们。
任何想要将 SQL DateTime2 正确恢复为 DateTime 的人,包括 'Kind=Utc'
(DateTime)reader["ConcertEnd"].ToUniversalTime();
否则 DateTime 可能很难确定日期来自哪个时区