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

保存时,返回一个错误:

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

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

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

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

问题

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


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

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

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


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


简短的回答

如果没有初始化DateTime字段的值,就会发生这种情况;该字段不接受NULL值,并且它是一个值类型,因此将使用不可空的DateTime类型的默认值。

设置值固定它为我!

长回答

默认值(DateTime)为DateTime。MinValue(或新的DateTime(1,1,1)或01/01/0001),这不是一个有效的SQL日期时间值。

由于使用的是公历,SQL Server datetime的最低有效值是01/01/1753。但是SQL Server DateTime2支持从01/01/0001开始的日期。实体框架默认使用DateTime2来表示日期,因此生成的SQL隐式地将生成的DateTime2值强制转换为SQL服务器端的DateTime值。


在我的SQL Server 2008数据库中,我有一个标记为不可空的DateTime列,但有一个GetDate()函数作为其默认值。当使用EF4插入新对象时,我得到了这个错误,因为我没有显式地在对象上传递DateTime属性。我期望SQL函数为我处理日期,但它没有。我的解决方案是从代码中发送日期值,而不是依赖数据库来生成它。

obj.DateProperty = DateTime.now; // C#

实体框架4使用datetime2数据类型,因此在数据库中对应的字段必须是datetime2的SQL Server 2008。

要解决这个问题,有两种方法。

要在实体框架4中使用datetime数据类型,你必须将edmx文件中的ProviderManifestToken切换为“2005”。 如果你设置相应的字段为允许空(它转换为NULLABLE),那么EF自动使用日期对象作为datetime。


在我的例子中,我们将一个Date转换为一个Datetime,我们得到了这个错误。 结果是Date具有“更面向程序员”的最小值01/01/0001,而Datetime则停留在1753

将此与我们的数据收集错误结合起来,您就得到了异常!


这个人快把我逼疯了。我想避免使用可空的日期时间(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;
                    }
                }
            }
        }
    }
}

对我来说,这是因为约会时间是…

01/01/0001 00:00:00

在这种情况下,你想要分配null给你EF DateTime对象…以我的FirstYearRegistered代码为例

DateTime FirstYearRegistered = Convert.ToDateTime(Collection["FirstYearRegistered"]);
if (FirstYearRegistered != DateTime.MinValue)
{
    vehicleData.DateFirstReg = FirstYearRegistered;
}  

有时它在开发机器上工作得很好,而在服务器上则不行。在我的例子中,我必须写:

<globalization uiCulture="es" culture="es-CO" />

在网络上。配置文件。

机器(服务器)中的时区是正确的(CO地区),但web应用程序不是。这个设置完成了,它再次工作正常。

当然,所有的约会都是有价值的。

:D


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

我遇到了这个问题,并将以下内容添加到我的datetime属性中:

 [Column(TypeName = "datetime2")]
 public DateTime? NullableDateTimePropUtc { get; set; }

有时EF不知道它是在处理计算列还是触发器。按照设计,这些操作将在插入操作后的EF之外设置一个值。

修复方法是在EF的edmx中为StoreGeneratedPattern属性中的列指定Computed。

对我来说,这是当列有一个插入当前日期和时间的触发器时,参见下面的第三部分。


解决方法

在Visual Studio中打开模型浏览器页面,然后是模型,然后是实体类型->

选择实体和日期时间属性 选择StoreGeneratedPattern 设置为Computed


对于这种情况,其他答案是变通的,因为列的目的是在创建记录时指定一个时间/日期,而SQL的任务是执行一个触发器来添加正确的时间。例如下面的SQL触发器:

DEFAULT (GETDATE()) FOR [datecrecreated]。


您将有日期列,它被设置为允许的数据时间的最小值,如1/1/1001。

为了克服这个问题,你可以为ur属性设置正确的datetime值,也可以设置另一个神奇的属性,如IsSpecified=true。


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

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

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

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


正如andyuk已经指出的那样,当NULL值被分配给一个不可空的DateTime字段时,就会发生这种情况。考虑将DateTime更改为DateTime?或可空< DateTime >。请记住,如果您正在使用依赖属性,还应该确保您的依赖属性的类型也是一个可空的DateTime类型。

下面是一个不完整的DateTime到DateTime的真实示例?引起奇怪行为的类型调整


如果我们不传递一个日期时间到日期时间字段,默认日期{1/1/0001 12:00:00 AM}将被传递。

但是这个日期与实体框架工作不兼容,所以它会抛出 将datetime2数据类型转换为datetime数据类型会导致值超出范围

只需要默认DateTime。如果您没有传递任何日期,那么现在进入日期字段。

movie.DateAdded = System.DateTime.Now

将此代码添加到ASP中的类中。NET为我工作:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Properties<DateTime>().Configure(c => c.HasColumnType("datetime2"));
}

我意识到了这个问题,你们也应该意识到:

https://en.wikipedia.org/wiki/Year_2038_problem

在SQL中,创建了一个新的字段类型来避免这个问题(datetime2)。

这个“Date”字段类型与DateTime . net类具有相同的范围值。它将解决您的所有问题,所以我认为解决它的最佳方法是改变数据库列类型(这不会影响您的表数据)。


看看下面两个: 1)该字段没有NULL值。例如:

 public DateTime MyDate { get; set; }

替换:

public DateTime MyDate { get; set; }=DateTime.Now;

2)重新创建数据库。例如:

db=new MyDb();

继承的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


当我想用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");

    }
}

我在一个简单的控制台应用程序项目中遇到了这个问题,我的快速解决方案是通过运行这个方法将任何可能的datetime2日期转换为可空的datetime:

static DateTime? ParseDateTime2(DateTime? date)
    {
        if (date == null || date.ToString() == "1/1/0001 12:00:00 AM")
        {
            return null;
        }
        else
        {
            return date;
        }
    }

这当然不是一个完全全面的方法,但它满足了我的需要,也许它会帮助其他人!


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

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


在模型类的属性上添加下面提到的属性。

Attribute = [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
Reference = System.ComponentModel.DataAnnotations.Schema

最初我忘记添加这个属性。在我的数据库中,约束是这样创建的

ALTER TABLE [dbo].[TableName] ADD DEFAULT (getdate()) FOR [ColumnName]

我添加了这个属性并更新了我的db,然后它就变成了

ALTER TABLE [dbo].[TableName] ADD CONSTRAINT [DF_dbo.TableName_ColumnName] DEFAULT (getdate()) FOR [ColumnName]

对我来说,我有一个Devexpress DateEdit组件,它通过nullable model属性绑定到可空的datetime MSSQL列。我所要做的就是在DateEdit上设置AllowNullInput = True。将其设置为“默认”会导致日期1.1.0001出现-仅在离开DateEdit之前-然后由于上面提到的后续指示,我得到了此转换错误消息。


在我的例子中,当为Nullable DateTime列显式分配NULL值时,然后尝试保存更改。这个错误将会弹出。


Code First上下文:

从这里开始

    public DateTime Created { get; set; }

这个。添加[DatabaseGenerated(DatabaseGeneratedOption.Computed)]属性。

    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public DateTime Created { get; set; }

在你的模型中。

一定要把这个也加到最上面

using System.ComponentModel.DataAnnotations.Schema;

已经有很多好的答案了。我想展示一种使用实体框架core fluent api来解决这个问题的方法。 大多数情况下,错误发生在默认情况下生成DateTime值时,因此您需要覆盖DataContext中的OnModelCreating,并在您的特定实体的属性中手动添加默认值,以便EF能够正确地转换到数据库,如下所示:

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {

        modelBuilder.Entity<MyEntity>(entity =>
        {
            entity.ToTable("MyTable");

            entity.Property(e => e.MyColumnDateTime)
                .HasDefaultValueSql("GETDATE()");
        });

        OnModelCreatingPartial(modelBuilder);
    }