我试图在SQL server 2008 R2中存储. net TimeSpan。

EF Code First似乎建议它应该存储为SQL中的时间(7)。

然而。net中的TimeSpan可以处理超过24小时的时间。

在SQL server中存储。net TimeSpan的最佳方法是什么?


当前回答

我会存储时间跨度。然后使用Timespan.FromSeconds(TotalSeconds)检索它。

根据你需要的分辨率,你可以使用TotalMilliseconds, TotalMinutes, TotalDays。

您还可以在数据库中调整浮点数的精度。

这不是一个确切的值……但是这样做的好处是它很容易在简单的查询中读取和计算。

其他回答

没有直接的对等物。只需以数字形式存储,例如秒数或适合您所需精度的内容。

现在,使用EF Core,您可以在AppDbContext中透明地转换数据类型

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
      // i.e. Store TimeSpan as string (custom)
      modelBuilder
        .Entity<YourClass>()
        .Property(x => x.YourTimeSpan)
        .HasConversion(
            timeSpan => timeSpan.ToString(), // To DB
            timeSpanString => TimeSpan.Parse(timeSpanString) // From DB
        );

    // i.e. Store TimeSpan as string (using TimeSpanToStringConverter)
    modelBuilder
        .Entity<YourClass>()
        .Property(x => x.YourTimeSpan)
        .HasConversion(new TimeSpanToStringConverter());

      // i.e. Store TimeSpan as number of ticks (custom)
      modelBuilder
        .Entity<YourClass>()
        .Property(x => x.YourTimeSpan)
        .HasConversion(
            timeSpan => timeSpan.Ticks, // To DB
            timeSpanString => TimeSpan.FromTicks(timeSpanString) // From DB
        );

    // i.e. Store TimeSpan as number of ticks (using TimeSpanToTicksConverter)
    modelBuilder
        .Entity<YourClass>()
        .Property(x => x.YourTimeSpan)
        .HasConversion(new TimeSpanToTicksConverter());
}

我将它作为BIGINT存储在数据库中,我将存储tick的数量(例如。时间间隔。蜱虫属性)。

这样,如果我想在检索时获得一个TimeSpan对象,我只需执行TimeSpan. fromticks (value),这很简单。

我知道这是一个老问题,但我想确保注意到一些其他选项。

由于您不能在time sql datatype字段中存储大于24小时的TimeSpan;其他一些选择可能是。

Use a varchar(xx) to store the ToString of the TimeSpan. The benefit of this is the precision doesn't have to be baked into the datatype or the calculation, (seconds vs milliseconds vs days vs fortnights) All you need to to is use TimeSpan.Parse/TryParse. This is what I would do. Use a second date, datetime or datetimeoffset, that stores the result of first date + timespan. Reading from the db is a matter of TimeSpan x = SecondDate - FirstDate. Using this option will protect you for other non .NET data access libraries access the same data but not understanding TimeSpans; in case you have such an environment.

为了与最可能生成时间跨度(计算2倍或date-times的差异)的来源保持一致,您可能希望将. net TimeSpan存储为SQL Server DateTime类型。

这是因为在SQL Server中,2个DateTime的差值(转换为Float's,然后转换回DateTime)只是相对于1900年1月1日的DateTime。例:+0.1秒就是1900年1月1日00:00:00.100,-0.1秒就是1899年12月31日23:59:59.900。

要将. net TimeSpan转换为SQL Server DateTime类型,首先要将其添加到1900年1月1日的DateTime中,从而将其转换为. net DateTime类型。当然,当你把它从SQL Server读入。net时,你会先把它读入。net DateTime,然后减去1900年1月1日,将它转换成。net TimeSpan。

For use cases where the time spans are being generated from SQL Server DateTime's and within SQL Server (i.e. via T-SQL) and SQL Server is prior to 2016, depending on your range and precision needs, it may not be practical to store them as milliseconds (not to mention Ticks) because the Int Type returned by DateDiff (vs. the BigInt from SS 2016+'s DateDiff_Big) overflows after ~24 days worth of milliseconds and ~67 yrs. of seconds. Whereas, this solution will handle time spans with precision down to 0.1 seconds and from -147 to +8,099 yrs..

警告:

This would only work if the difference relative to Jan. 1, 1900 would result in a value within the range of a SQL Server DateTime Type (Jan. 1, 1753 to Dec. 31, 9999 aka -147 to +8,099 yrs.). We don't have to worry near as much on the .NET TimeSpan side, since it can hold ~29 k to +29 k yrs. I didn't mention the SQL Server DateTime2 Type (whose range, on the negative side, is much greater than SQL Server DateTime's), because: a) it cannot be converted to a numeric via a simple Cast and b) DateTime's range should suffice for the vast majority of use cases. SQL Server DateTime differences computed via the Cast - to - Float - and - back method does not appear to be accurate beyond 0.1 seconds.