【问题标题】:How do I map TimeSpan with greater than 24 hours to SQL server Code First?如何将大于 24 小时的 TimeSpan 映射到 SQL Server Code First?
【发布时间】:2012-01-20 03:33:01
【问题描述】:

我正在尝试将 TimeSpan Code First 属性映射到 SQL 服务器。 Code First 似乎将其创建为 SQL 中的 Time(7)。但是 .Net 中的 TimeSpan 可以处理超过 24 小时的时间,我需要存储超过 24 小时的事件长度。使用 Code First 处理此问题的最佳方法是什么。

【问题讨论】:

    标签: sql-server entity-framework ef-code-first code-first


    【解决方案1】:

    首先,MVC 与这个问题无关。它与 EF Code First 和 SQL Server 完全相关,因此是 DAL 问题。

    一种解决方案可能是在您的实体配置中提供自定义列类型,如下所示:

    modelBuilder
    .Entity<MyClass>()
    .Property(c => c.MyTimeSpan)
    .HasColumnType("whatever sql type you want to use");
    

    【讨论】:

    • 好的。这是我关心的你想使用的任何 sql 类型。将 .Net TimeSpan 映射到 SQL 服务器字段的标准方法是什么。
    • 我觉得已经够清楚了。 HasColumnType 方法的字符串参数必须包含您的 SQL 类型,就像您在 sql 脚本或表设计器中声明它一样,如 nvarchar(50) 或 bit 或任何您需要且与您正在使用的 .Net 数据类型兼容的东西.对于在您的特定情况下使用的确切类型是什么,只需进行试验。
    • 我知道如何更改列类型,这不是问题。将 .Net TimeSpan 映射到 SQL 似乎是一个相当常见的问题。我想具体了解将 .Net TimeSpan 存储到 SQL 服务器的最佳方式。
    • 那么您的问题根本与 Code First 无关,这是一个更普遍的问题。它更像是“与 .Net Timespan 关联的正确 SQL 类型是什么”。我给出了这样的答案,因为你问如何在 Code First 中做到这一点,我给了你一个 Code First 示例。
    【解决方案2】:

    根据我的previous question 关于如何在 SQL 中存储 TimeSpan 的内容,我被建议将其存储为秒或刻度等。最后我没有映射 TimeSpan 列,因为 SQL 服务器中没有对应的列。我只是创建了一个将 TimeSpan 转换为刻度并将其存储在数据库中的第二个字段。然后我阻止存储 TimeSpan

    public Int64 ValidityPeriodTicks { get; set; }
     
    [NotMapped]
    public TimeSpan ValidityPeriod
    {
        get { return TimeSpan.FromTicks(ValidityPeriodTicks); }
        set { ValidityPeriodTicks = value.Ticks; }
    }
    

    如果您希望在 EF Core 中执行此操作,则可以使用 Value Conversions,这样会更简洁。在 2.1 中,您可以使用值转换和 TimeSpanToTicksConverter 将时间跨度透明地映射到数据库中的刻度。所以当然值得考虑 EF Core(假设其他功能满足需求)——可以在 Framework 4.7 项目中使用它,因此不需要切换到 .Net Core。

    【讨论】:

    • 当有人不知道或忘记 ValidityPeriod 是 NotMapped 属性时,这种方法可能会导致查询不理想。如果它在查询 EF 不会抱怨的 LINQ 中使用,它只会拉取集合并对其进行迭代。出于这个原因,人们可能会使用老式的 Get/Set 访问器来明确它们不应该在查询中使用。
    • 同意,我已经在我的解决方案中调整了我的代码,以便实现更清晰。
    • 使用扩展方法获取或设置值,应该少一些误会。
    • 根据 StanislawSwierc 的评论,如何:而不是 NotMapped 属性,创建一个“GetValidityPeriod():TimeSpan”方法和一个“SetValidityPeriod(period:TimeSpan):void”方法。这样一来,它显然是未映射的,并且显然不应该在 Linq 查询中使用。
    【解决方案3】:

    据我所知,SQL Server 中没有针对 .NET 的 TimeSpan 的等效数据类型。最接近的匹配是时间,但是,正如您所指出的,它只支持最多 24 小时的值? http://msdn.microsoft.com/en-us/library/ms186724.aspx#DateandTimeDataTypes

    下面的 MSDN 文档描述了这个http://msdn.microsoft.com/en-us/library/bb386909.aspx。我假设由于那里没有列出解决方案,因此目前不可能。

    【讨论】:

    • 是的,除了我的答案,我从来没有发现过。 EF 似乎做出了将其映射到显然不匹配的 SQL Server Time 数据类型的奇怪决定
    猜你喜欢
    • 2011-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多