我正在使用Entity Framework 4.1中引入的DbContext和Code First API .
data model 使用基本数据类型,例如 string
和 DateTime
. 我在某些情况下使用的唯一数据注释是 [Required]
,但这不在任何 DateTime
属性上 . 例:
public virtual DateTime Start { get; set; }
DbContext subclass 也很简单,看起来像:
public class EventsContext : DbContext
{
public DbSet<Event> Events { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Event>().ToTable("Events");
}
}
initializer 将模型中的日期设置为今年或明年的合理值 .
但是当我运行初始化程序时,我在 context.SaveChanges()
收到此错误:
将datetime2数据类型转换为日期时间数据类型会导致超出范围的值 . 该语句已终止 .
我不明白为什么会发生这种情况,因为一切都很简单 . 我也不确定如何解决它,因为没有edmx文件可以编辑 .
有任何想法吗?
11 回答
您必须确保Start大于或等于SqlDateTime.MinValue(1753年1月1日) - 默认情况下,Start等于DateTime.MinValue(0001年1月1日) .
简单 . 首先在代码中,将DateTime的类型设置为DateTime? . 因此,您可以在数据库中使用可空的DateTime类型 . 实体示例:
在某些情况下,
DateTime.MinValue
(或等效,default(DateTime)
)用于表示未知值 . 这个简单的扩展方法应该有助于解决问题:用法:
如果符合您特定的建模问题,您可以使该字段为空 . 空日期不会像默认值那样被强制转换为不在SQL DateTime类型范围内的日期 . 另一个选择是明确映射到不同的类型,也许是,
虽然这个问题已经很老了,并且已经有了很好的答案,但我认为我应该再提一个解释这个问题的3种不同方法 .
1st Approach
在表格的相应列中将
DateTime
属性public virtual DateTime Start { get; set; }
显式映射到datetime2
. 因为默认情况下EF会将其映射到datetime
.这可以通过流畅的API或数据注释来完成 .
在DbContext类中覆盖
OnModelCreating
并配置属性Start
(出于解释原因,它是EntityClass类的属性) .2nd Approach
将
Start
初始化为EntityClass构造函数中的默认值 . 这很好,好像由于某种原因,在将实体保存到数据库之前未设置Start
的值,start将始终具有默认值 . 确保默认值大于或等于SqlDateTime.MinValue(从1753年1月1日到9999年12月31日)3rd Approach
使
Start
成为可以为空的DateTime
-note?
DateTime
之后 -如需更多解释,请阅读post
我的解决方案是将所有datetime列切换到datetime2,并将datetime2用于任何新列 . 换句话说,默认情况下,EF使用datetime2 . 将其添加到上下文的OnModelCreating方法:
这将获得所有DateTime和DateTime?所有实体的属性 .
如果您的
DateTime
属性在数据库中可以为空,那么请务必使用DateTime?
作为关联的对象属性,否则EF将传入DateTime.MinValue
以获取超出SQL日期时间类型可处理范围的未分配值 .初始化构造函数中的Start属性
当我尝试使用Code First向ASP .Net Identity Framework的Users表(AspNetUsers)添加一些新字段时,这对我有用 . 我在IdentityModels.cs中更新了Class - ApplicationUser,并添加了DateTime类型的字段lastLogin .
我有同样的问题,在我的情况下,我将日期设置为新的DateTime()而不是DateTime.Now
在我的情况下,这发生在我使用实体并且sql表具有默认值datetime == getdate()时 . 所以我做了什么来为这个领域设置一个值 .
我正在使用Database First,当我发生这个错误时,我的解决方案是在edmx文件中强制使用ProviderManifestToken =“2005”(使模型与SQL Server 2005兼容) . 不知道Code First是否有类似的东西 .