7

我意识到这可能是一个骗局,但我花了几个小时寻找答案,但似乎找不到。

我目前正在创建一个检索音乐会数据的 Web 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.Data.dll 中出现“System.IndexOutOfRangeException”类型的异常,但未在用户代码中处理

我已经尝试了很多事情并遵循了很多示例和代码,但我似乎无法正确转换它。有人有想法吗?

解决方案

我忘记在查询中添加“concertStart”和“concertEnd”。问题已解决,谢谢!

4

4 回答 4

8

首先,如果您想读取 and 的值ConcertStartConcertEnd您必须将它们包含在您的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 Server 数据库中读取值完全没有问题DATETIME2(3)

reader.GetFieldValue<DateTime>(reader.GetOrdinal("ConcertEnd"));

那对你有用吗?

于 2015-02-28T10:49:07.233 回答
1

问题是在您的选择中,您只返回所需的 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 DateTime2vs .Net无关——ADODateTime可以很好地绑定这些。

于 2015-02-28T10:51:10.450 回答
0

我会用我在这里找到的扩展方法来做

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

希望这可以帮助!

于 2015-02-28T10:49:04.153 回答
0

任何想要将 SQL DateTime2 正确恢复为 DateTime 的人,包括'Kind=Utc'

(DateTime)reader["ConcertEnd"].ToUniversalTime();

否则 DateTime 可能很难确定日期来自哪个时区

于 2018-12-28T09:50:44.723 回答