这意味着,根据所读取的内容,我的datatable具有DateTime2类型,而我的数据库具有DateTime类型;这是错误的。将datetime2数据类型转换为datetime数据类型导致超出范围的值
日期列被设置为 DateTime,代码如下:
new DataColumn("myDate", Type.GetType("System.DateTime"))
问题:这个问题可以在代码中解决还是需要在数据库层面上进行更改?
这意味着,根据所读取的内容,我的datatable具有DateTime2类型,而我的数据库具有DateTime类型;这是错误的。将datetime2数据类型转换为datetime数据类型导致超出范围的值
new DataColumn("myDate", Type.GetType("System.DateTime"))
问题:如果您没有对 DateTime 字段初始化值,则可能会发生此情况;该字段不接受 NULL 值,且它是一个值类型,因此将使用非可空 DateTime 类型的默认值。
对其设置值即可解决问题!
default(DateTime)
的值为 DateTime.MinValue
(或 new DateTime(1, 1, 1)
或 01/01/0001),这不是有效的 SQL datetime
值。
由于 SQL Server 使用公历,因此 SQL Server datetime 的最低有效值为 01/01/1753
。但是,SQL Server DateTime2 支持从 01/01/0001 开始的日期。Entity Framework 默认使用 DateTime2 表示日期,因此生成的 SQL 隐式地将生成的 DateTime2 值强制转换为 SQL Server 上的 DateTime 值。
在.NET中,DATETIME
和DATETIME2
都映射到System.DateTime
- 你不能真正进行“转换”,因为它们实际上是相同的.NET类型。
请参阅MSDN文档页面:http://msdn.microsoft.com/en-us/library/bb675168.aspx
这两者的"SqlDbType
"有两个不同的值-你可以在DataColumn
定义中指定吗?
但是:在SQL Server上,支持的日期范围非常不同。
DATETIME
支持1753/1/1到“永恒”(9999/12/31),而DATETIME2
支持0001/1/1到永恒。
因此,你真正需要做的是检查日期的年份 - 如果在1753年之前,则需要将其更改为1753之后的日期,以便SQL Server中的DATETIME
列可以处理它。
Marc
DtInit = new System.DateTime(1492, 10, 12)
失败了。 - KiquenetDateTime
列,并且其默认值为GetDate()
函数。但是在使用EF4插入新对象时,由于没有明确传递一个DateTime属性,我遇到了这个错误。我本以为SQL函数会自动处理日期,但实际上并没有。我的解决方案是从代码中发送日期值而不是依赖数据库来生成它。obj.DateProperty = DateTime.now; // C#
Nullable<DateTime>
,并且在代码中我可以将其保留为空(而不是01/01/0000)。令人惊喜的是,我发现EF到SQL知道忽略此插入中的null,并使用服务器上的日期(GetDate()
)...对我们来说,这甚至更可取,因为我们需要更好的服务器一致性,而不必担心Web服务器和SQL服务器之间的时钟差异。 - Funka对于我来说,这是因为日期时间是...
01/01/0001 00:00:00
在这种情况下,您想将null分配给EF DateTime对象...以我的FirstYearRegistered代码为例。
DateTime FirstYearRegistered = Convert.ToDateTime(Collection["FirstYearRegistered"]);
if (FirstYearRegistered != DateTime.MinValue)
{
vehicleData.DateFirstReg = FirstYearRegistered;
}
这个问题让我很烦恼。我想避免使用可空的日期时间 (DateTime?
)。我也不能使用 SQL Server 2008 的 datetime2
类型。
modelBuilder.Entity<MyEntity>().Property(e => e.MyDateColumn).HasColumnType("datetime2");
最终我选择了以下内容:
public class MyDb : DbContext
{
public override int SaveChanges()
{
UpdateDates();
return base.SaveChanges();
}
private void UpdateDates()
{
foreach (var change in ChangeTracker.Entries<MyEntityBaseClass>())
{
var values = change.CurrentValues;
foreach (var name in values.PropertyNames)
{
var value = values[name];
if (value is DateTime)
{
var date = (DateTime)value;
if (date < SqlDateTime.MinValue.Value)
{
values[name] = SqlDateTime.MinValue.Value;
}
else if (date > SqlDateTime.MaxValue.Value)
{
values[name] = SqlDateTime.MaxValue.Value;
}
}
}
}
}
}
[Column(TypeName = "datetime2")]
? - Kiquenetedmx
中为该列指定Computed
,并将其放置于StoreGeneratedPattern
属性中。
对我而言,当该列有一个插入当前日期和时间的触发器时,就会出现这种情况,详见下面的第三部分。
解决方法
在 Visual Studio 中打开 Model Browser
页面,然后选择 Model
,再选择 Entity Types
-> 然后
StoreGeneratedPattern
Computed
DEFAULT (GETDATE()) FOR [DateCreated]
。GETDATE()
。但最近有人评论说,任何 DateTime2 操作都应该使用 SYSDATETIME()
,我认为这是正确的。 - ΩmegaMan我遇到了这个问题,于是我在我的日期时间属性中添加了以下内容:
[Column(TypeName = "datetime2")]
public DateTime? NullableDateTimePropUtc { get; set; }
System.ComponentModel.DataAnnotations.Schema;
。 - Kiquenet如果我们不向日期时间字段传递日期时间,则会传递默认日期{1/1/0001 12:00:00 AM}。
但是,这个日期与实体框架不兼容,因此会抛出“将datetime2数据类型转换为datetime数据类型时,结果值超出范围”的错误。
如果您没有传递任何日期,请将default DateTime.now
设为日期字段的默认值。
movie.DateAdded = System.DateTime.Now
最简单的方法是将您的数据库更改为使用datetime2而不是datetime。兼容性很好,您将不会遇到错误。
您仍然需要进行大量测试......
错误可能是因为您尝试将日期设置为0年或其他一些值 - 但这完全取决于您有哪些控制权来更改内容。