首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用实体框架Codefirst - SqlDbType.Time溢出存储SqlDbType.Time

使用实体框架Codefirst - SqlDbType.Time溢出存储SqlDbType.Time
EN

Stack Overflow用户
提问于 2013-06-16 03:03:24
回答 5查看 32.7K关注 0票数 34

我正在尝试在我的DB中添加一些常量:

代码语言:javascript
复制
context.Stages.AddOrUpdate(s => s.Name,
                                   new Stage()
                                   {
                                       Name = "Seven",
                                       Span = new TimeSpan(2, 0, 0),
                                       StageId = 7
                                   });
context.Stages.AddOrUpdate(s => s.Name,
                                   new Stage()
                                   {
                                       Name = "Eight",
                                       Span = new TimeSpan(1, 0, 0, 0),
                                       StageId = 8
                                   });

这是属于EF迁移的Seed()函数中的。它在第八阶段失败如下:

System.Data.UpdateException:更新条目时出错。有关详细信息,请参阅内部异常。-> System.OverflowException: SqlDbType.Time溢出。值'1.00:00:00‘超出范围。必须在00:00:00.0000000和23:59:59.9999999之间。

为什么我不能用EF储存一个时差?我真的希望我不需要在这里的两端做一些愚蠢的时间转换.

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2013-06-16 07:51:20

在这一行:

代码语言:javascript
复制
Span = new TimeSpan(1, 0, 0, 0)

您正在使用此构造函数:

代码语言:javascript
复制
public TimeSpan(int days, int hours, int minutes, int seconds);

因此,在将TimeSpan传递给days参数后,实际上要创建一个大于24小时的Time,而基础数据库类型是Time,它只接受00:00-23:59之间的值。

很难说您是否真的打算有一个1天的TimeSpan,或者它只是一个错误。

如果您真的想要一个大于24小时的TimeSpan,我想您必须将您的字段映射到另一种数据库类型(如SmallDateTime)。

如果只是错误,只需将行更改为:

代码语言:javascript
复制
Span = new TimeSpan(1, 0, 0),
票数 9
EN

Stack Overflow用户

发布于 2015-01-20 04:04:56

代码语言:javascript
复制
    [Browsable(false)]
    [EditorBrowsable(EditorBrowsableState.Never)]
    [Obsolete("Property '" + nameof(Duration) + "' should be used instead.")]        
    public long DurationTicks { get; set; }

    [NotMapped]
    public TimeSpan Duration
    {
#pragma warning disable 618
      get { return new TimeSpan(DurationTicks); }
      set { DurationTicks = value.Ticks; }
#pragma warning restore 618
    }

更新

这现在是可以实现的,因为EFCore2.1使用了价值转换

代码语言:javascript
复制
builder.Entity<Stage>()
    .Property(s => s.Span)
    .HasConversion(new TimeSpanToTicksConverter()); // or TimeSpanToStringConverter
票数 48
EN

Stack Overflow用户

发布于 2019-11-27 18:37:00

在两端进行计时转换不再是愚蠢的了。不确定何时添加它,但是Entity现在将选择适当的内置转换器(在本例中为TimeSpanToTicksConverter)。您所需要做的就是向实体类中添加一个属性,实体框架将自动地给SQL表中的列与TimeSpan类相同的范围。

代码语言:javascript
复制
public class Stage
{
    public string Name { get; set; }

    [Column(TypeName = "bigint")]
    public TimeSpan Span { get; set; }

    public int StageId { get; set; }
}

我确信bigint不是TimeSpan的默认列类型,因为它具有可读性和向后兼容性,但这似乎是一个非常完美的解决方案。

我希望这对六年后经历这一问题的任何人都有帮助。

文档:https://learn.microsoft.com/en-us/ef/core/modeling/value-conversions

票数 15
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17129795

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档