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

174

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 del método Editar:

<% using (Html.BeginForm()) {%>

    <fieldset>
        <legend>Fields</legend>
        <p>
            <label for="headline">Headline</label>
            <%= Html.TextBox("headline") %>
        </p>
        <p>
            <label for="story">Story <span>( HTML Allowed )</span></label>
            <%= Html.TextArea("story") %>
        </p>
        <p>
            <label for="image">Image URL</label>
            <%= Html.TextBox("image") %>
        </p>
        <p>
            <input type="submit" value="Post" />
        </p>
    </fieldset>

<% } %>

Cuando presiono el botón Enviar {"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."}aparece el error: ¿ Alguna idea de cuál es el problema? 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 gusta ... Aunque no veo por qué está involucrada la fecha, ya que no se menciona en el método controlador para editar?

Cameron
fuente
1
modelBuilder.Entity<WorldInfo>().Property(d => d.CurrentTime).HasColumnType("datetime2");
Anthony Nichols

Respuestas:

166

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

En lugar de usar ApplyPropertyChanges, sugiero recuperar el objeto que se está modificando, cambiar los campos específicos que edita su formulario y luego guardar el objeto con esas modificaciones; de esa manera, 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 concurrentes.

Actualizar:

Aquí hay una muestra no probada de solo actualizar algunos campos de su objeto (esto supone que está utilizando 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();
Jacob
fuente
Muy útil :) Me preguntaba por qué se modificaba la fecha cuando no la había especificado. ¿Puedes ayudar a cambiar el método de edición para que ya no use ApplyPropertyChanges? Como soy nuevo en ASP.NET y no lo entiendo completamente por el momento. Gracias compañero.
Cameron
¿Qué pasa si quiero establecer la fecha a la fecha actual, es decir. la fecha y hora en que se actualizó el artículo? Como esa probablemente sea la mejor opción y supongo que funcionaría con ApplyPropertyChanges que tengo en juego.
Cameron
Vea mi edición (se supone que ese modifiedDatees el nombre de su propiedad)
Jacob
SubmitChanges no funciona en mi aplicación: / ¿es posible agregar el story.modifiedDate = DateTime.Now;bit a mi código actual? Gracias
Cameron
1
este error ocurre cuando configuramos DateTime CreatedDate público en lugar de public DateTime? CreatedDate, porque DateTime no puede ser nulo, por lo que da un error fuera de rango. Puede ser útil, pero resolvió mi problema.
Adnan
115

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

El objeto datetime predeterminado se crea con un valor de 01/01/1000y se usará en lugar de nulo. Esto se enviará a la columna de fecha y hora que puede contener valores de fecha en 1753-01-01 00:00:00adelante, pero no antes, lo que lleva a la excepción de 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.

Sanjay Kumar Madhva
fuente
3
Esto sucede cuando el campo de fecha y hora en la base de datos es opcional y el valor no está establecido. Por lo tanto, este no es un error común de las personas, este es uno de los problemas arquitectónicos de EF.
GSoft Consulting
1
Estoy de acuerdo en que EF debería ver el tipo en DB y ajustar en consecuencia o lanzar o al menos lanzar un error más preciso. Por el lado positivo, me gusta su respuesta, ya que proporcionó 2 opciones en lugar de la habitual: inicialice el archivo con el valor mínimo.
DanteTheSmith
43

DATETIMEadmite 1753/1/1 hasta "eternity" (9999/12/31), mientras que DATETIME2admite 0001/1/1 hasta la eternidad.

Msdn

Respuesta: Supongo que intenta guardar DateTimecon el valor '0001/1/1'. Sólo hay que establecer punto de interrupción y depurarlo, si es así, sustituir DateTimecon nullo conjunto de fecha normal.

Andrew Orsich
fuente
¿Qué pongo en el controlador? La depuración solo muestra el error que publiqué anteriormente. Gracias.
Cameron
parece un error aquí -> _db.SaveChanges (); Puede establecer un punto de interrupción antes de esta línea ...
Andrew Orsich
Sí lo hice Luego dice que hay un error en SaveChanges, así que miro la InnerException y dice que es por el error publicado, ¡así que ese es el error!
Cameron
¿Ha verificado el valor de DateTime antes de _db.SaveChanges (); fue llamado? Debería ser genial que '1753/1/1'.
Andrew Orsich el
El valor original de la fecha del artículo es {18/10/2009 00:00:00} y el valor de la fecha de ArticleToEdit es {01/01/0001 00:00:00}, por lo que parece que está tratando de cambiar la fecha a 1 de todo lo que no es No quiero, pero no explica por qué arroja el error, ya que el formato es el mismo, ¿verdad?
Cameron
14

Este me estaba volviendo loco. Quería evitar el uso de una fecha y hora anulables ( DateTime?). Tampoco tenía la opción de usar el tipo datetime2 de SQL 2008 ( modelBuilder.Entity<MyEntity>().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<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;
                    }
                }
            }
        }
    }
}
sky-dev
fuente
10

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

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

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

Patricio
fuente
5

Recibí este error después de cambiar 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 la instrucción UPDATE de SQL manualmente para inicializar el campo con un valor estándar.

Otra solución podría ser especificar el valor predeterminado para el archivo.

Aleksandr Khomenko
fuente
3

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

StinkyCat
fuente
3

Parece que está utilizando el marco de la 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 por defecto. Agregue esto al método OnModelCreating en su contexto:

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

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

Ogglas
fuente
2

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

Por lo tanto, asegúrese de que su modelo tenga un valor de fecha y hora antes de guardar los cambios o que sea anulable 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 persistir en la base de datos:

public DateTime DateAdded { get; set; }
public DateTime? ReleaseDate { get; set; }
Willy David Jr
fuente
2

Si está utilizando Entity Framework versión> = 5, la aplicación de la anotación [DatabaseGeneratedOption.Computed]] a las propiedades DateTime de su clase permitirá que el desencadenador de la tabla de la base de datos haga su trabajo de ingresar fechas para la creación y actualización de registros sin causar su código de Entity Framework para amordazar.

[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.

Jim Kay
fuente
1

Además, si no conoce parte del código en el que se produjo el error, puede perfilar la ejecución sql "incorrecta" utilizando el perfilador sql integrado en mssql.

El parámetro de fecha y hora incorrecto mostrará algo así:

mal param

Nigrimista
fuente
1

Este problema generalmente ocurre cuando intenta actualizar una entidad. Por ejemplo, tiene una entidad que contiene un campo llamado DateCreatedque es [Obligatorio] y cuando inserta el registro, no se devuelve ningún error, pero cuando desea actualizar esa entidad en particular, obtiene el

error de conversión de fecha y hora fuera de rango.

Ahora aquí está la solución:

En su vista de edición, es decir, edit.cshtmlpara los usuarios de MVC, todo lo que necesita hacer es agregar un campo de formulario oculto DateCreatedjusto debajo del campo oculto para la clave principal de los datos de edición.

Ejemplo:

@Html.HiddenFor(model => model.DateCreated)

Agregando esto a su vista de edición, nunca tendrá ese error, se lo aseguro.

Aduwu Joseph
fuente
1

Debe habilitar el valor nulo para su variable de fecha:

 public Nullable<DateTime> MyDate{ get; set; }
Badr Bellaj
fuente
0

Intente hacer que su propiedad sea anulable.

    public DateTime? Time{ get; set; }

Trabajó para mi.

typhon04
fuente
0

Si tiene acceso a la base de datos, puede cambiar el tipo de columna de la base de datos de fecha y hora a fecha y hora2 (7) todavía enviará un objeto de fecha y hora y se guardará

Sergiu Mindras
fuente
0

El modelo debe tener fecha y hora anulables. El método sugerido anteriormente para recuperar el objeto que debe modificarse debe usarse 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 completo del servicio 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();
anu
fuente
0

[Resuelto] En Entity Framework Code First (mi caso) simplemente cambiando DateTimepara DateTime?resolver mi problema.

/*from*/ public DateTime SubmitDate { get; set; }
/*to  */ public DateTime? SubmitDate { get; set; }
Amir Astaneh
fuente
0

Error: la conversión de un tipo de datos datetime2 a un tipo de datos datetime dio como resultado un valor fuera de rango.

Este error ocurrió cuando debido a NO asignar ningún valor a una columna de fecha NO NULA en SQL DB usando EF y se resolvió asignando el mismo.

¡Espero que esto ayude!

usuario2964808
fuente
0

Tengo este problema cuando creé mis clases desde el enfoque de Base de datos primero. Resuelto usando simplemente Convert.DateTime (dateCausingProblem) De hecho, siempre intente convertir los valores antes de pasar, lo salva de valores inesperados.

Ansar nisar Gill
fuente
0

debe hacer coincidir el formato de entrada de su campo de fecha con el formato de entidad requerido que es aaaa / mm / dd

bagazo
fuente
1
Hay otras respuestas que proporcionan la pregunta del OP, y se publicaron hace algún tiempo. Cuando publique una respuesta, vea: ¿Cómo escribo una buena respuesta? , asegúrese de agregar una nueva solución o una explicación sustancialmente mejor, especialmente al responder preguntas anteriores.
help-info.de