我有一个5列的数据表,其中一行被数据填充,然后通过事务保存到数据库。
保存时,返回一个错误:
将datetime2数据类型转换为datetime数据类型会导致值超出范围
它暗示,正如阅读,我的数据表有一个类型的DateTime2和我的数据库一个DateTime;这是错误的。
date列设置为DateTime,如下所示:
新数据专栏(“myDate, Type.GetType”)
问题
是否可以在代码中解决这个问题,或者是否必须在数据库级别上更改某些内容?
我有一个5列的数据表,其中一行被数据填充,然后通过事务保存到数据库。
保存时,返回一个错误:
将datetime2数据类型转换为datetime数据类型会导致值超出范围
它暗示,正如阅读,我的数据表有一个类型的DateTime2和我的数据库一个DateTime;这是错误的。
date列设置为DateTime,如下所示:
新数据专栏(“myDate, Type.GetType”)
问题
是否可以在代码中解决这个问题,或者是否必须在数据库级别上更改某些内容?
当前回答
这个人快把我逼疯了。我想避免使用可空的日期时间(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;
}
}
}
}
}
}
其他回答
最简单的方法是将数据库更改为使用datetime2而不是datetime。兼容性工作得很好,你不会得到你的错误。
你仍然需要做一堆测试……
这个错误可能是因为您试图将日期设置为0年或其他什么-但这完全取决于您可以在哪里控制更改内容。
这个人快把我逼疯了。我想避免使用可空的日期时间(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;
}
}
}
}
}
}
Code First上下文:
从这里开始
public DateTime Created { get; set; }
这个。添加[DatabaseGenerated(DatabaseGeneratedOption.Computed)]属性。
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime Created { get; set; }
在你的模型中。
一定要把这个也加到最上面
using System.ComponentModel.DataAnnotations.Schema;
继承的datetime属性有问题
当不可为空的日期字段在插入/更新时值为null时,通常会显示此错误消息。其中一个原因可能是遗传。
如果你的日期是从基类继承的,你不做映射EF将不会读取它的值。
欲了解更多信息: https://weblogs.asp.net/manavi/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-3-table-per-concrete-type-tpc-and-choosing-strategy-guidelines
创建一个基于@sky-dev实现的基类。所以这可以很容易地应用到多个上下文和实体中。
public abstract class BaseDbContext<TEntity> : DbContext where TEntity : class
{
public BaseDbContext(string connectionString)
: base(connectionString)
{
}
public override int SaveChanges()
{
UpdateDates();
return base.SaveChanges();
}
private void UpdateDates()
{
foreach (var change in ChangeTracker.Entries<TEntity>())
{
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;
}
}
}
}
}
}
用法:
public class MyContext: BaseDbContext<MyEntities>
{
/// <summary>
/// Initializes a new instance of the <see cref="MyContext"/> class.
/// </summary>
public MyContext()
: base("name=MyConnectionString")
{
}
/// <summary>
/// Initializes a new instance of the <see cref="MyContext"/> class.
/// </summary>
/// <param name="connectionString">The connection string.</param>
public MyContext(string connectionString)
: base(connectionString)
{
}
//DBcontext class body here (methods, overrides, etc.)
}