实体框架和SqlDateTime溢出的最佳实践

5

System.DateTime 可以接受比 SQL Server 的 DateTime 更广泛的值。因此,有一个名为 System.Data.SqlTypes.SqlDateTime 的类来模拟后者。

因此,我本来期望 Entity Framework 选择 SqlDateTime,但它没有这样做。

所以我的问题是...

有什么最佳实践可以确保您的 DateTime 值在保存到数据库时不会出现问题?

是否有任何方法强制 EF 使用 SqlDateTime?

3个回答

4

有几件事情可以做:

  • 如果使用的是 SQL Server 2008 或更新版本,可以在数据库中使用 DATEDATETIME2 数据类型,它们提供与 .NET 的 DateTime 相同的日期范围。

  • 如果无法使用这些新数据类型,则需要在将数据存储到持久存储之前,在日期字段上进行一些检查/验证。EF EntityObject 提供了很多方法来插入验证和保存对象的过程 - 选择适合您的方法。


1
也许这是一个旧的线程,但我会为其他人发布我的发现:
假设我们有开发环境:EF 5、CodeFirst、SqlCE 4.0:
public abstract class Entity : IEntity, IEquatable<Entity>
{
public virtual int Id { get; protected set; }
public virtual DateTime LastModified { get; set; }

[DataType(DataType.Date)]
public virtual DateTime CreatedOn { get; set; }

[DataType(DataType.DateTime)]
public virtual DateTime CreatedOn2 { get; set; }

[DataType(DataType.Time)]
public virtual DateTime CreatedOn3 { get; set; }

public virtual DateTime CreatedOn4 { get; set; }
}

使用这样的自定义映射:
public EntityMapping()
{
HasKey(e => e.Id);
Property(e => e.Id);
Property(e => e.LastModified).IsRequired().IsConcurrencyToken();
Property(e => e.CreatedOn).IsRequired();
Property(e => e.CreatedOn2).IsRequired();
Property(e => e.CreatedOn3).IsRequired();
Property(e => e.CreatedOn4).IsRequired();
}

这会生成 this,意味着我们将遇到溢出异常。
在仍然使用 SQL CE 4.0 的情况下更改映射如下:
Property(e => e.CreatedOn).IsRequired().HasColumnType("datetime2");
Property(e => e.CreatedOn2).IsRequired().HasColumnType("date");
Property(e => e.CreatedOn3).IsRequired().HasColumnType("date");
Property(e => e.CreatedOn4).IsRequired().HasColumnType("datetime2");

error转换成SQL Server Standart 2012似乎解决了问题(这当然不是一个解决方案-只是为了实验)。创建的SQL Server模式是this

我不是Sql方面的专家,但看起来SQL CE不支持这些日期。开发环境的问题仍然存在。DateTime可以被替换,但可能需要在这里和那里进行大量的重构。

还要记住SqlDateTime和DateTime非常不同

我认为好的解决方案-对于代码和项目生命周期-是根据stackoverflow上的一个链接建议在LocalDb和SQL标准之间切换,再加上自定义的fluentApi映射设置来平衡模型创建或两者兼而有之。

引入EF中的自定义约定作为安全保障也是个不错的选择。

如果有更好的全方位解决方案,适用于代码和开发生产环境,请发帖分享。


1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接