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

Tengo el siguiente código en mi HomeController:

public ActionResult Edit(int id) { var ArticleToEdit = (from m in _db.ArticleSet where m.storyId == id select m).First(); return View(ArticleToEdit); } [ValidateInput(false)] [AcceptVerbs(HttpVerbs.Post)] public ActionResult Edit(Article ArticleToEdit) { var originalArticle = (from m in _db.ArticleSet where m.storyId == ArticleToEdit.storyId select m).First(); if (!ModelState.IsValid) return View(originalArticle); _db.ApplyPropertyChanges(originalArticle.EntityKey.EntitySetName, ArticleToEdit); _db.SaveChanges(); return RedirectToAction("Index"); } 

Y esta es la vista para el método de edición:

  
Fields

Cuando pulso el botón de enviar, aparece el error: {"The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value.\r\nThe statement has been terminated."} Cualquier idea sobre qué ¿el problema es? Supongo que el método de edición está tratando de actualizar el valor publicado en el DB al editado, pero por alguna razón no le está gustando … Aunque no veo por qué está involucrada la fecha, ya que no se menciona en el método del controlador para editar?

El problema es que está utilizando ApplyPropertyChanges con un objeto modelo que solo se ha ApplyPropertyChanges con datos en el formulario (título, historia e imagen). ApplyPropertyChanges aplica cambios a todas las propiedades del objeto, incluido DateTime no inicializado, que se establece en 0001-01-01, que está fuera del rango de DATETIME de SQL Server.

En lugar de usar ApplyPropertyChanges , sugeriría recuperar el objeto que se está modificando, cambiar los campos específicos que su formulario edita, y luego guardar el objeto con esas modificaciones; De esa forma, solo se modifican los campos modificados. Alternativamente, puede colocar entradas ocultas en su página con los otros campos poblados, pero eso no sería muy amigable con las ediciones simultáneas.

Actualizar:

Aquí hay una muestra no probada de simplemente actualizar algunos campos de su objeto (esto es asumiendo que está usando LINQ to SQL):

 var story = _db.ArticleSet.First(a => a.storyId == ArticleToEdit.storyId); story.headline = ArticleToEdit.headline; story.story = ArticleToEdit.story; story.image = ArticleToEdit.image; story.modifiedDate = DateTime.Now; _db.SubmitChanges(); 

Este es un error común al que las personas se enfrentan al usar Entity Framework. Esto ocurre cuando la entidad asociada a la tabla que se está guardando tiene un campo obligatorio de fecha y hora y no se establece con algún valor.

El objeto datetime predeterminado se crea con un valor de 01/01/1000 y se usará en lugar de null. Esto se enviará a la columna de fecha y hora, que puede contener valores de fecha desde 1753-01-01 00:00:00 adelante, pero no antes, lo que lleva a la excepción fuera de rango.

Este error puede resolverse modificando el campo de la base de datos para aceptar nulo o inicializando el campo con un valor.

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

Msdn

Respuesta: Supongo que intentas guardar DateTime con el valor ‘0001/1/1’. Simplemente configure el punto de interrupción y depórelo, si es verdadero, luego reemplace DateTime con nulo o establezca la fecha normal.

Este me estaba volviendo loco. Quería evitar el uso de una fecha de vencimiento nulo ( DateTime? ). No tuve la opción de utilizar el tipo datetime2 de SQL 2008 ( 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; } } } } } } 

Si tiene una columna que es datetime y permite null obtendrá este error. Recomiendo establecer un valor para pasar al objeto antes de .SaveChanges ();

También puede solucionar este problema agregando al modelo (Entity Framework version> = 5)

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

Recibí este error después de haber cambiado mi modelo (código primero) de la siguiente manera:

 public DateTime? DateCreated 

a

 public DateTime DateCreated 

Las filas actuales con valor nulo en DateCreated causaron este error. Así que tuve que usar SQL UPDATE Statement manualmente para inicializar el campo con un valor estándar.

Otra solución podría ser una especificación del valor predeterminado para el archivo.

En mi caso, en el inicializador de la clase que estaba usando en la tabla de la base de datos, no estaba estableciendo ningún valor predeterminado para mi propiedad DateTime, por lo tanto, el problema se explicó en la respuesta de @Andrew Orsich ‘. Así que acabo de hacer la propiedad nullable. O también podría haberle dado DateTime.Now en el constructor. Espero que ayude a alguien.

Parece que estás usando el marco de entidad. Mi solución fue cambiar todas las columnas de fecha y hora a datetime2, y usar datetime2 para cualquier columna nueva, en otras palabras, hacer que EF use datetime2 de forma predeterminada. Agregue esto al método OnModelCreating en su contexto:

 modelBuilder.Properties().Configure(c => c.HasColumnType("datetime2")); 

Eso obtendrá todo el DateTime y DateTime? propiedades en todas las entidades en su modelo.

Si está utilizando la versión de Entity Framework> = 5, aplicar la anotación [DatabaseGenerated (DatabaseGeneratedOption.Computed)] a sus propiedades DateTime de su clase permitirá que el desencadenante de la tabla de la base de datos haga su trabajo de introducir fechas para la creación de registros y la actualización de registros sin causar su código de Entity Framework para gag.

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

Esto es similar a la sexta respuesta, escrita por Dongolo Jeno y editada por Gille Q.

Además, si no conoce parte del código donde ocurrió el error, puede perfilar la ejecución “mala” de sql utilizando el perfilador sql integrado a mssql.

El parámetro malo de datetime mostrará algo así:

mal param

Tuve el mismo problema, desafortunadamente, tengo dos propiedades DateTime en mi modelo y una propiedad DateTime es nula antes de guardar SaveChanges.

Por lo tanto, asegúrese de que su modelo tenga el valor DateTime antes de guardar los cambios o hacer que sea nulo para evitar errores:

 public DateTime DateAdded { get; set; } //This DateTime always has a value before persisting to the database. public DateTime ReleaseDate { get; set; } //I forgot that this property doesn't have to have DateTime, so it will trigger an error 

Así que esto resuelve mi problema, es cuestión de asegurarse de que la fecha de su modelo sea correcta antes de continuar en la base de datos:

 public DateTime DateAdded { get; set; } public DateTime? ReleaseDate { get; set; } 

Intenta hacer que tu propiedad sea nulable.

  public DateTime? Time{ get; set; } 

Trabajó para mi.

Si tiene acceso a la base de datos, puede cambiar el tipo de columna de la base de datos de datetime a datetime2 (7), aún enviará un objeto de fecha y hora y se guardará

El modelo debe tener datetime nullable. El método sugerido anteriormente para recuperar el objeto que se debe modificar se debe usar en lugar de applyPropertyChanges. En mi caso, tenía este método para guardar mi objeto:

 public ActionResult Save(QCFeedbackViewModel item) 

Y luego en servicio, recupero usando:

 RETURNED = item.RETURNED.HasValue ? Convert.ToDateTime(item.RETURNED) : (DateTime?)null 

El código de servicio completo es el siguiente:

  var add = new QC_LOG_FEEDBACK() { QCLOG_ID = item.QCLOG_ID, PRE_QC_FEEDBACK = item.PRE_QC_FEEDBACK, RETURNED = item.RETURNED.HasValue ? Convert.ToDateTime(item.RETURNED) : (DateTime?)null, PRE_QC_RETURN = item.PRE_QC_RETURN.HasValue ? Convert.ToDateTime(item.PRE_QC_RETURN) : (DateTime?)null, FEEDBACK_APPROVED = item.FEEDBACK_APPROVED, QC_COMMENTS = item.QC_COMMENTS, FEEDBACK = item.FEEDBACK }; _context.QC_LOG_FEEDBACK.Add(add); _context.SaveChanges(); 

[Solucionado] En Entity Framework Code First (mi caso) simplemente cambiando DateTime a DateTime? resolver mi problema

 /*from*/ public DateTime SubmitDate { get; set; } /*to */ public DateTime? SubmitDate { get; set; }