我有一个5列的数据表,其中一行被数据填充,然后通过事务保存到数据库。

保存时,返回一个错误:

将datetime2数据类型转换为datetime数据类型会导致值超出范围

它暗示,正如阅读,我的数据表有一个类型的DateTime2和我的数据库一个DateTime;这是错误的。

date列设置为DateTime,如下所示:

新数据专栏(“myDate, Type.GetType”)

问题

是否可以在代码中解决这个问题,或者是否必须在数据库级别上更改某些内容?


当前回答

当我想用ASP编辑一个页面时,我看到了这个错误。净MVC。我没有问题,而创建,但更新数据库使我的DateCreated属性超出范围!

当您不希望您的DateTime属性为空,并不想检查它的值是否在sql DateTime范围(和@Html。HiddenFor没有帮助!),只需在相关类(控制器)中添加一个静态DateTime字段,并在GET操作时给它一个值,然后在POST执行它的工作时使用它:

public class PagesController : Controller
{
    static DateTime dateTimeField;
    UnitOfWork db = new UnitOfWork();

    // GET:
    public ActionResult Edit(int? id)
    {
        Page page = db.pageRepository.GetById(id);
        dateTimeField = page.DateCreated;
        return View(page);
    }

    // POST: 
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit(Page page)
    {
        page.DateCreated = dateTimeField;
        db.pageRepository.Update(page);
        db.Save();
        return RedirectToAction("Index");

    }
}

其他回答

检查DB中的req格式。例如我的DB有默认值或Binding (((1)/(1))/(1900))

System.DateTime MyDate = new System.DateTime( 1900 ,1, 1);

创建一个基于@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.)
 }

最简单的方法是将数据库更改为使用datetime2而不是datetime。兼容性工作得很好,你不会得到你的错误。

你仍然需要做一堆测试……

这个错误可能是因为您试图将日期设置为0年或其他什么-但这完全取决于您可以在哪里控制更改内容。

我发现这篇文章试图弄清楚为什么我总是得到以下错误,这是由其他答案解释的。

将datetime2数据类型转换为datetime数据类型会导致值超出范围。

使用可空的DateTime对象。 公共DateTime ?PurchaseDate{获取;设置;}

如果你使用实体框架 将edmx文件中的nullable属性设置为True

DATETIME和DATETIME2都映射到System。. net中的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