La conversión de un tipo de datos datetime2 a un tipo de datos datetime da como resultado un valor fuera de rango

Tengo una tabla de datos con 5 columnas, donde una fila se llena con datos y luego se guarda en la base de datos a través de una transacción.

Mientras se guarda, se devuelve un error:

La conversión de un tipo de datos datetime2 a un tipo de datos datetime resultó en un valor fuera de rango

Implica, como se lee, que mi datatable tiene un tipo de DateTime2 y mi base de datos un DateTime ; eso está mal.

La columna de fecha se establece en un DateTime como este:

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

Pregunta

¿Se puede resolver esto en código o tiene que cambiarse algo a nivel de base de datos?

¿Qué tipo de fechas tienes en la columna?

¿Todos encajan dentro del rango del tipo?


Como un lado, la forma correcta de obtener un objeto Type para el constructor DataColumn es el tipo de typeof clave, que es de órdenes de magnitud más rápido.

Por lo tanto, para crear la columna, debe escribir

 new DataColumn("myDate", typeof(DateTime)) 

Esto puede suceder si no asigna un valor a un campo DateTime cuando el campo no acepta valores NULL.

¡Eso lo solucionó!

Tanto DATETIME como DATETIME2 correlacionan con System.DateTime en .NET: no se puede hacer una “conversión”, ya que es realmente del mismo tipo .NET.

Consulte la página de documentación de MSDN: http://msdn.microsoft.com/en-us/library/bb675168.aspx

Hay dos valores diferentes para ” SqlDbType ” para estos dos: ¿puede especificarlos en su definición de DataColumn ?

PERO: en SQL Server, el rango de fechas admitido es bastante diferente.

DATETIME admite 1753/1/1 a “eternidad” (9999/12/31), mientras que DATETIME2 admite 0001/1/1 hasta la eternidad.

Entonces, lo que realmente necesita hacer es verificar el año de la fecha; si es antes de 1753, debe cambiarlo a algo DESPUÉS de 1753 para que la columna DATETIME en SQL Server lo maneje.

Bagazo

En mi base de datos de SQL Server 2008, tenía una columna DateTime marcada como no anulable, pero con una función GetDate() como valor predeterminado. Al insertar un objeto nuevo usando EF4, obtuve este error porque no estaba pasando una propiedad DateTime en mi objeto explícitamente. Esperaba que la función SQL manejara la fecha para mí, pero no fue así. Mi solución fue enviar el valor de fecha del código en lugar de confiar en la base de datos para generarlo.

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

para mí fue porque la fecha era …

01/01/0001 00:00:00

en este caso, quiere asignarle un nulo EF DateTime Object … usando mi código FirstYearRegistered como ejemplo

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

Este me estaba volviendo loco. Quería evitar el uso de una fecha de vencimiento nulo ( DateTime? ). No tenía la opción de utilizar el tipo de datetime2 y datetime2 SQL Server 2008 tampoco

 modelBuilder.Entity().Property(e => e.MyDateColumn).HasColumnType("datetime2"); 

Finalmente opté por lo siguiente:

 public class MyDb : DbContext { public override int SaveChanges() { UpdateDates(); return base.SaveChanges(); } private void UpdateDates() { foreach (var change in ChangeTracker.Entries()) { 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; } } } } } } 

A veces EF no sabe que se trata de una columna calculada o un disparador . Por diseño, esas operaciones establecerán un valor fuera de EF después de una inserción.

La solución es especificar Computed en el edmx de EF para esa columna en la propiedad StoreGeneratedPattern .

Para mí fue cuando la columna tenía un disparador que insertaba la fecha y la hora actuales, ver abajo en la tercera sección.


Pasos para resolver

En Visual Studio, abra la página del Model Browser Model luego Entity Types Model luego en Entity Types -> then

  1. Seleccione la entidad y la propiedad de fecha y hora
  2. Seleccione StoreGeneratedPattern
  3. Establecer en Computed

Cuadro de diálogo Modelo de entidad de modelo de navegador EF


Para esta situación, otras respuestas son soluciones temporales, ya que el objective de la columna es tener una fecha / hora especificada cuando se creó el registro, y ese es el trabajo de SQL para ejecutar un desencadenador para agregar la hora correcta. Tal como este disparador de SQL:

DEFAULT (GETDATE()) FOR [DateCreated] .

Si no pasamos el campo de fecha y hora de la fecha, se pasará la fecha predeterminada {1/1/0001 12:00:00 AM}.

Pero esta fecha no es compatible con el trabajo de marcos de entidades, por lo que arrojará la conversión de un tipo de datos de fecha y hora a un tipo de datos de fecha y hora como resultado de un valor fuera de rango.

Simplemente default DateTime.now en el campo de fecha si no está pasando ninguna fecha.

 movie.DateAdded = System.DateTime.Now 

Me encontré con esto y agregué lo siguiente a mi propiedad datetime:

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

Lo más fácil sería cambiar su base de datos para usar datetime2 en lugar de datetime. La compatibilidad funciona bien, y no obtendrá sus errores.

Aún querrás hacer un montón de pruebas …

El error probablemente se deba a que intentas establecer una fecha para el año 0 o algo así, pero todo depende de dónde tengas el control para cambiar cosas.

Encontré esta publicación tratando de entender por qué recibí el siguiente error que se explica por las otras respuestas.

La conversión de un tipo de datos datetime2 a un tipo de datos datetime resultó en un valor fuera de rango.

Use un objeto de fecha / hora nullable.
público DateTime? PurchaseDate {get; conjunto; }

Si está utilizando la infraestructura de la entidad Establezca la propiedad que admite nulos en el archivo edmx en True

Establezca la propiedad que admite nulos en el archivo edmx en ** True **

Entity Framework 4 funciona con el tipo de datos datetime2, por lo que en db el campo correspondiente debe ser datetime2 para SQL Server 2008.

Para alcanzar la solución hay dos formas.

  1. Para utilizar el tipo de datos de fecha y hora en Entity Framwork 4, debe cambiar el ProviderManifestToken en el archivo edmx a “2005”.
  2. Si configura el campo correspondiente como Permitir nulo (lo convierte en NULLABLE) entonces EF usa automáticamente los objetos de fecha como fecha y hora.

Como andyuk ya ha señalado, esto puede suceder cuando se asigna un valor NULL a un campo DateTime que no admite nulos . Considere cambiar DateTime a DateTime? o Nullable < DateTime >. Tenga en cuenta que, en caso de que esté utilizando una propiedad de dependencia , también debe asegurarse de que el tipo de propiedad de la dependencia sea también un tipo de fecha y hora con capacidad de nulos.

A continuación se muestra un ejemplo de la vida real de un DateTime incompleto para DateTime? ajuste de tipo que plantea el comportamiento extraño

enter image description here

Creó una clase base basada en la implementación @ sky-dev. Entonces, esto se puede aplicar fácilmente a múltiples contextos y entidades.

 public abstract class BaseDbContext : 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()) { 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; } } } } } } 

Uso:

 public class MyContext: BaseDbContext { ///  /// Initializes a new instance of the  class. ///  public MyContext() : base("name=MyConnectionString") { } ///  /// Initializes a new instance of the  class. ///  /// The connection string. public MyContext(string connectionString) : base(connectionString) { } //DBcontext class body here (methods, overrides, etc.) } 

En mi caso estábamos lanzando una Fecha a un Fecha y recibimos este error. Lo que ocurre es que Date tiene un mínimo de 01/01/0001 “más orientado al progtwigdor”, mientras que Datetime está bloqueado en 1753.

¡Combina eso con un error de recostackción de datos de nuestra parte y obtienes tu excepción!

Algunas veces funciona bien en máquinas de desarrollo y no en servidores. En mi caso tuve que poner:

  

En el archivo web.config.

La zona horaria en la máquina (Servidor) era correcta (en la configuración regional de CO) pero la aplicación web no. Esta configuración está hecha y funcionó bien de nuevo.

Por supuesto, todas las fechas tenían valor.

:RE

tendrá la columna de fecha que se configuró en lesathan el valor mínimo de tiempo permitido como 1/1/1001.

Para superar este problema, puede establecer el valor de fecha y hora adecuado para su propiedad y también establecer otra propiedad mágica como IsSpecified = true.