将datetime2数据类型转换为日期时间数据类型会导致超出范围的值

Ger*_*and 356 c# sql-server orm datetime entity-framework

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

保存时,会返回错误:

将datetime2数据类型转换为日期时间数据类型会导致超出范围的值

这意味着,正如所读,我的数据表有一种类型DateTime2和我的数据库a DateTime; 那是错的.

日期列设置为DateTime如下所示:

new DataColumn("myDate", Type.GetType("System.DateTime"))

这可以在代码中解决,还是必须在数据库级别上进行更改?

and*_*yuk 710

如果在字段不接受NULL值时未向DateTime字段分配值,则会发生这种情况.

那为我修好了!

  • 在Entity Framework中,如果添加一个非空的Created列,那么当你没有在代码中设置值时,更新你的EDMX会以这种方式抛出这个错误 (42认同)
  • 我认为它发生的是EntityFramework看到DateTime.MinValue是年0001,并且在SQL datetime超出范围值,所以它将此值作为DateTime2(支持年0001)值发送,因此插入/更新有效,但是当SQL尝试将此DateTime2转换为DateTime时,它会失败,因为这会导致不同的值.有两种解决方案:1在模型中使用可为空的日期时间或2.在保存上下文更改之前,将所有日期时间值初始化为正确的值.您的选择取决于日期时间在模型中的含义. (29认同)
  • 为什么实体框架不能忽略NULL,因为在我的SQL端,我有一个默认值= getdate()? (15认同)
  • 是什么修好了你?如果您有一个带有getdate()调用的日期时间字段作为默认值,则会出现此错误. (6认同)
  • @GuillermoRuffino 的解决方案对我有用。检查所有字段并找到那些 0001 年的条目。 (2认同)

mar*_*c_s 152

.NET中的DATETIMEDATETIME2映射System.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之后的某个东西,以便DATETIMESQL Server中的列来处理它.

  • 这解释了我遇到的问题.虽然很少有情况需要处理1753/1/1之前的实际日期,但是在很多情况下,其中一个获得可能导致错误的默认值0001/1/1. (6认同)

SLa*_*aks 58

专栏中有哪些日期?

所有这些都适合该类型的范围吗?


顺便说一句,获取构造函数Type对象的正确方法DataColumntypeof关键字,它的速度要快几个数量级.

因此,要创建列,您应该编写

new DataColumn("myDate", typeof(DateTime))
Run Code Online (Sandbox Code Playgroud)

  • 我改变了我的datacolumns并现在使用了typeof ...进一步我发现了我的问题.有1个数据行包含错误的日期,触发了错误 (3认同)

Gra*_*ham 40

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

obj.DateProperty = DateTime.now; // C#
Run Code Online (Sandbox Code Playgroud)

  • 乐意效劳.这很烦人,因为您认为EF数据上下文能够在从表创建对象时发现该字段具有默认值. (2认同)
  • 我在2周前在VS Live上看到了EF Code First的演示,看起来很棒,顺便说一句. (2认同)

JGi*_*tin 31

对我来说这是因为日期时间是..

01/01/0001 00:00:00

在这种情况下,你要分配空给你EF DateTime对象......用我FirstYearRegistered代码为例

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


sky*_*dev 20

这个让我发疯.我想避免使用可以为空的日期时间(DateTime?).我也没有选择使用SQL Server 2008的datetime2类型

modelBuilder.Entity<MyEntity>().Property(e => e.MyDateColumn).HasColumnType("datetime2");
Run Code Online (Sandbox Code Playgroud)

我最终选择了以下内容:

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;
                    }
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Ωme*_*Man 20

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

修复是Computed在EF edmx中为StoreGeneratedPattern属性中的该列指定.

对我而言,当列具有插入当前日期和时间的触发器时,请参见下面的第三部分.


要解决的步骤

在Visual Studio中打开Model Browser页面Model然后Entity Types- >然后

  1. 选择实体和日期时间属性
  2. 选择 StoreGeneratedPattern
  3. 调成 Computed

EF模型浏览器模型实体类型对话框


对于这种情况,其他答案是解决方法,因为列的目的是在创建记录时指定时间/日期,这是SQL执行触发器以添加正确时间的作业.比如这个SQL触发器:

DEFAULT (GETDATE()) FOR [DateCreated].


Rog*_*ala 10

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

 [Column(TypeName = "datetime2")]
 public DateTime? NullableDateTimePropUtc { get; set; }
Run Code Online (Sandbox Code Playgroud)


Lij*_*ijo 9

如果我们没有传递日期时间到日期时间字段,则将传递默认日期{1/1/0001 12:00:00 AM}.

但是这个日期与实体框架工作不兼容,因此它会将 datetime2数据类型转换为日期时间数据类型,从而导致超出范围的值

只是default DateTime.now到日期字段,如果你不传递任何日期.

movie.DateAdded = System.DateTime.Now
Run Code Online (Sandbox Code Playgroud)


Rob*_*ley 6

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

你仍然想做一堆测试......

错误可能是因为你试图将日期设置为0年级或者其他东西 - 但这一切都取决于你有什么控制来改变东西.