我正在尝试在DB中添加一些常量:
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 Codefirst迁移的Seed()函数中。它在第八阶段失败,出现以下情况:
System.Data.UpdateException:更新条目时出错。有关详细信息,请参见内部异常。- --> System. OverflowException:SqlDbType。时间溢出。值“1.00:00:00”超出范围。必须介于00:00:00.0000000和23:59:59.999999之间。
为什么我不能使用EF存储时间跨度?我真的希望我不需要做一些愚蠢的时间到刻度转换两端在这里。
5条答案
按热度按时间pbossiut1#
更新
从EF Core 2.1开始,使用Value Conversion就可以实现这一点。
eqqqjvef2#
在两端进行时间到刻度的转换不再是愚蠢的。不确定他们是什么时候添加的,但实体框架现在将选择适当的内置转换器(如果存在)(在本例中是TimeSpanToTicksConverter)。你所需要做的就是给你的实体类添加一个属性,实体框架会自动给予SQL表中的列一个与TimeSpan类相同的范围。
我确信bigint不是TimeSpan的默认列类型,以便于可读性和向后兼容,但这似乎是一个非常完美的解决方案。
我希望这对六年后遇到这个问题的人有所帮助。
文件:https://learn.microsoft.com/en-us/ef/core/modeling/value-conversions
oxalkeyp3#
在这一行中:
您使用的是以下构造函数:
因此,实际上您创建的
TimeSpan
大于24小时,因为您将1
传递给days
参数,而您的基础数据库类型是Time
,它只接受00:00-23:59之间的值。很难判断你是否真的打算用1天的
TimeSpan
,或者它只是一个打字错误。如果你真的想要一个大于24小时的
TimeSpan
,我想你必须把你的字段Map到另一个数据库类型(比如SmallDateTime
)。如果只是一个打字错误,只需将您的行改为:
nvbavucw4#
现在EF Core内置了
ticks
<=>TimeSpan
转换。你所要做的就是:不需要示例化一个新的
TimeSpanToTicksConverter
或任何东西。只需指定类型long
作为泛型参数,就完成了。有关更多信息,请参阅EF Core内置价值转换器
a2mppw5e5#
如前所述,问题在于EF将TimeSpan类Map到Time,该时间被限制为24小时。
如果您需要存储超过24小时的时间跨度,我建议使用以下两种方法之一:
**1)**为一个时间跨度的不同元素创建一个具有int属性的TimeSpan实体,类似于:
只需将适用实体中的外部引用添加到自定义Timespan实体中即可。
**2)**做一些愚蠢的时间到滴答的转换,如blog post中所解释的。