【问题标题】:Converting DateTime to SmallDateTime in c#在 C# 中将 DateTime 转换为 SmallDateTime
【发布时间】:2013-06-05 16:25:36
【问题描述】:

如何在 c# 中将 datetime 转换为 smalldatetime?我正在获取日期,我需要将其转换为符合数据库。 sql中禁止更改列的数据类型。

【问题讨论】:

  • 请出示相关代码。你说你正在转换,但你的意思是在 where 子句中吗?在反序列化到您的实体期间?还有什么?
  • 而且由于这是向下转换,您最好解释一下您想要从小日期时间边界边缘的值中得到什么。
  • @MattJohnston 我正在使用实体框架。我想我需要写一个触发器来解决这个问题。

标签: c# asp.net entity-framework


【解决方案1】:

您可以为实体框架模型使用 .NET DateTime 类型,但告诉 EF 它在数据库中使用非默认列类型。为此,您可以重写 DbContext 的 OnModelCreating 方法,并使用 HasColumnType 方法:

public class Foo    
{
    public int Id { get; set; }
    public DateTime IAmSoSmall { get; set; }    // wants to be smalldatetime in SQL
}

public class MyContext : DbContext
{
    public DbSet<Foo> Foos { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        var foo = modelBuilder.Entity<Foo>();
        foo.Property(f => f.IAmSoSmall).HasColumnType("smalldatetime");

        base.OnModelCreating(modelBuilder);
    }
}

当然,您必须对 DateTime 属性进行适当的范围检查,以确保存储的值介于 SQL 的 smalldatetime 支持的值之间。我想你可以使用如下属性来做到这一点:

    [Range(typeof(DateTime), "1/1/1900", "6/6/2079")]
    public DateTime IAmSoSmall { get; set; }    // wants to be smalldatetime in SQL

...基于从 1900 年 1 月 1 日到 2079 年 6 月 6 日的有效范围,如 MSDN 中所述。

【讨论】:

  • 您还可以使用数据注释[Column(TypeName="smalldatetime")] 更改列类型。见stackoverflow.com/a/4833477/1180926
  • @Arithmomaniac 是的,看起来从 EF 4.3.1 开始,列类型数据注释有效。不错。
【解决方案2】:

Sql Server datetimesmalldatetime自动 映射到 CLR 的 System.DateTime 和从 CLR 的 System.DateTime 映射。 smalldatetime 的精度为 1 分钟; datetime 的精度约为 1/300 秒(不要问为什么。就是这样)。由于 CLR 的 System.DateTime1 具有 100 纳秒的精度,因此运行时负责舍入。

  • smalldatetime 内部是一个 32 位整数,包含自 smalldatetime 纪元 (1900-01-01 00:00) 以来的分钟数。

    在转换中,秒和小数秒使用 SQL Server 的神秘日期/时间舍入规则进行舍入,因此日期 2013-01-31 23:59:59 会舍入到下一个日期 2013-02-01 00 :00:00'。

  • datetime 内部是一对 32 位整数。高阶词是自纪元以来的天数;低位词是自一天开始 (00:00:00) 以来的毫秒数。 datetime 的纪元是 1900-01-01 00:00:00.000。

    再一次,值在转换中以同样神秘的方式四舍五入,小数秒被放入 SQL Server 的适当毫秒存储桶之一,是 3 毫秒的倍数 - 没有像 2013- 这样的 SQL Server `datetime 值05-01 13:57:23.004。这将“四舍五入”到 23.003 毫秒或 23.006 毫秒。

如果您想对事物进行更多控制,则需要先在 C# 中调整日期时间值,然后再将它们发送到数据库。

【讨论】:

  • 嗯? SQL Server 以 0.000、0.003 或 0.007 秒的增量计算时间,没有明显的原因。自 Sybase 时代以来一直如此。即便如此,在 Windows NT 下,BIOS 和 WinNT 系统时钟都有一个分辨率 c。 10 毫秒。 Sybase 必须使用 CMOS“实时”时钟实现自己的时间实现,绕过 BIOS。该芯片以 32.768 kHz 的频率运行,使二进制运算变得容易。为什么他们会将其锤入大小不均匀的桶中,这些桶与十进制值或二进制表示都不能很好地啮合。我相信当时有人觉得这很有意义。
  • 我第一次完全误读了,好像你说datetimesmalldatetime 的不同精度没有合理性,没有意识到你的paranthetical 指的是任意的datetime 的 1/300 秒精度。现在笨拙地删除我被误导的评论。
【解决方案3】:

也许您可以执行 YourDateTime.Date 之类的操作

通常,当你这样做时,它会将时间设置为 00:00:00。

【讨论】:

  • smalldatetime 可以表示时间分量。见the docs
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-19
  • 2019-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-24
相关资源
最近更新 更多