SB2*_*055 24 .net c# entity-framework ef-code-first
我正在尝试将一些常量添加到我的数据库中:
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
});
Run Code Online (Sandbox Code Playgroud)
这是我的用于EF Codefirst Migrations的Seed()函数.它在第八阶段失败,具体如下:
System.Data.UpdateException:更新条目时发生错误.有关详细信息,请参阅内部异常 ---> System.OverflowException:SqlDbType.Time溢出.值'1.00:00:00'超出范围.必须在00:00:00.0000000和23:59:59.9999999之间.
为什么我无法使用EF存储时间跨度?我真的希望我不需要在这两端做一些愚蠢的时间转换...
Shi*_*mmy 33
[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
}
Run Code Online (Sandbox Code Playgroud)
现在,这可以通过使用价值转换的 EF Core 2.1实现.
builder.Entity<Stage>()
.Property(s => s.Span)
.HasConversion(new TimeSpanToTicksConverter()); // or TimeSpanToStringConverter
Run Code Online (Sandbox Code Playgroud)
小智 11
在两端进行时间到滴答转换不再是愚蠢的。不确定他们何时添加它,但实体框架现在将选择适当的内置转换器(如果存在)(在本例中为 TimeSpanToTicksConverter)。您需要做的就是向实体类添加一个属性,实体框架将自动为 SQL 表中的列提供与 TimeSpan 类相同的范围。
public class Stage
{
public string Name { get; set; }
[Column(TypeName = "bigint")]
public TimeSpan Span { get; set; }
public int StageId { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我确信 bigint 不是 TimeSpan 的默认列类型,以实现人类可读性和向后兼容性,但这似乎是一个非常完美的解决方案。
我希望这可以帮助任何人在六年后遇到这个问题。
文档:https : //docs.microsoft.com/en-us/ef/core/modeling/value-conversions
Ami*_*adi 10
现在 EF Core 具有内置的ticks
<=>TimeSpan
转换。您所要做的就是:
builder.Property(p => p.SomeTimeSpanProperty)
.HasConversion<long>();
Run Code Online (Sandbox Code Playgroud)
无需实例化新的TimeSpanToTicksConverter
或任何东西。只需将类型指定long
为通用参数即可。
有关详细信息,请参阅EF Core 内置值转换器
在这一行:
Span = new TimeSpan(1, 0, 0, 0)
Run Code Online (Sandbox Code Playgroud)
你正在使用这个构造函数:
public TimeSpan(int days, int hours, int minutes, int seconds);
Run Code Online (Sandbox Code Playgroud)
因此,您实际创建的传输TimeSpan
时间超过了24小时,而您的基础数据库类型只接受00:00-23:59之间的值.1
days
Time
很难说你是否真的想要有TimeSpan
一天,或者只是一个错字.
如果你真的想要TimeSpan
超过24小时,我想你必须将你的字段映射到另一个数据库类型(如SmallDateTime
).
如果这只是一个拼写错误,只需将您的行更改为:
Span = new TimeSpan(1, 0, 0),
Run Code Online (Sandbox Code Playgroud)