La conversione di un tipo di dati datetime2 in un tipo di dati datetime ha prodotto un valore fuori range


174

Ho il seguente codice nel mio 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");
}

E questa è la vista per il metodo Edit:

<% 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>

<% } %>

Quando premo il pulsante Invia ricevo l'errore: {"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."}Qualche idea su quale sia il problema? Suppongo che il metodo di modifica stia tentando di aggiornare il valore pubblicato nel DB su modificato, ma per qualche motivo non gli piace ... Anche se non vedo perché la data è coinvolta in quanto non è menzionata nella metodo del controller per la modifica?


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

Risposte:


166

Il problema è che stai utilizzando ApplyPropertyChangesun oggetto modello che è stato popolato solo con i dati nel modulo (titolo, trama e immagine). ApplyPropertyChangesapplica le modifiche a tutte le proprietà dell'oggetto, incluso il non inizializzato DateTime, impostato su 0001-01-01, che non rientra nell'intervallo di SQL Server DATETIME.

Piuttosto che usare ApplyPropertyChanges, suggerirei di recuperare l'oggetto da modificare, cambiare i campi specifici che il modulo modifica, quindi salvare l'oggetto con quelle modifiche; in questo modo, vengono modificati solo i campi modificati. In alternativa, puoi inserire input nascosti nella tua pagina con gli altri campi popolati, ma ciò non sarebbe molto amichevole con le modifiche simultanee.

Aggiornare:

Ecco un esempio non testato di solo l'aggiornamento di alcuni campi del tuo oggetto (questo presuppone che tu stia utilizzando 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();

Molto utile :) Mi chiedevo perché la data fosse modificata quando non l'avevo specificata. Potete aiutarmi a cambiare il metodo Edit in modo che non utilizzi più ApplyPropertyChanges? Dato che sono nuovo di ASP.NET e al momento non capisco tutto. Grazie amico.
Cameron,

E se volessi impostare la data sulla data corrente, ad es. il datetime in cui l'articolo è stato aggiornato? Dato che probabilmente sarà l'opzione migliore e presumo che funzionerebbe con gli ApplyPropertyChanges che ho in gioco.
Cameron,

Vedi la mia modifica (presuppone che modifiedDatesia il nome della tua proprietà)
Jacob

SubmitChanges non funziona nella mia app: / è possibile aggiungere il story.modifiedDate = DateTime.Now;bit al mio codice attuale? Grazie
Cameron,

1
questo errore si verifica quando impostiamo DateTime CreatedDate pubblica anziché DateTime pubblica? CreatedDate, perché DateTime non può essere nullo, quindi perché è un errore fuori intervallo. può essere utile, ma ha risolto il mio problema.
adnan,

115

Questo è un errore comune che le persone affrontano quando usano Entity Framework. Ciò si verifica quando l'entità associata alla tabella da salvare ha un campo datetime obbligatorio e non lo si imposta con un valore.

L'oggetto datetime predefinito viene creato con un valore di 01/01/1000e verrà utilizzato al posto di null. Questo verrà inviato alla colonna datetime che può contenere i valori di data da1753-01-01 00:00:00 avanti, ma non prima, portando all'eccezione fuori intervallo.

Questo errore può essere risolto modificando il campo del database per accettare null o inizializzando il campo con un valore.


3
Ciò accade quando il campo datetime nel database è facoltativo e il valore non è impostato. Pertanto, questo non è un errore comune delle persone, questo è uno dei problemi di architettura EF.
GSoft Consulting,

1
Sono d'accordo che EF dovrebbe vedere il tipo in DB e regolare di conseguenza o lanciare o almeno lanciare un errore più preciso. Il lato positivo è che mi piace la tua risposta poiché hai fornito 2 opzioni anziché la solita: inizializza il file con un valore minimo.
DanteTheSmith

43

DATETIMEsupporta il 1753/1/1 fino all'eternità (9999/12/31), mentre DATETIME2supporta il 0001/1/1 fino all'eternità.

msdn

Risposta: Suppongo che provi a salvare DateTimecon il valore '0001/1/1'. Basta impostare il punto di interruzione ed eseguirne il debug, in tal caso quindi sostituire DateTimecon nullo impostare la data normale.


Cosa metto nel controller però? Il debug fa apparire quell'errore che ho pubblicato sopra. Grazie.
Cameron,

sembra un errore qui -> _db.SaveChanges (); È possibile impostare il punto di interruzione prima di questa riga ...
Andrew Orsich,

Sì ha fatto. Quindi dice che è un errore su SaveChanges, quindi guardo InnerException e dice che è a causa dell'errore pubblicato, quindi questo è l'errore!
Cameron,

Hai controllato il valore DateTime prima di _db.SaveChanges (); è stato chiamato? Sarebbe eccezionale rispetto al '1753/1/1'.
Andrew Orsich,

Il valore della data originale dell'articolo è {18/10/2009 00:00:00} e il valore della data ArticleToEdit è {01/01/0001 00:00:00}, quindi sembra che stia cercando di cambiare la data al 1 ° di tutto ciò che non è voglio che io voglia ma non spiega perché sta generando l'errore dato che il formato è lo stesso giusto?
Cameron,

14

Questo mi stava facendo impazzire. Volevo evitare di usare una data / ora nullable ( DateTime?). Non avevo nemmeno la possibilità di usare il tipo datetime2 di SQL 2008 (modelBuilder.Entity<MyEntity>().Property(e => e.MyDateColumn).HasColumnType("datetime2"); ).

Alla fine ho optato per il seguente:

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;
                    }
                }
            }
        }
    }
}

10

È inoltre possibile risolvere questo problema aggiungendo al modello (versione Entity Framework> = 5)

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

8

Se hai una colonna che è datetime e consente null, otterrai questo errore. Consiglio di impostare un valore da passare all'oggetto prima di .SaveChanges ();


5

Ho ricevuto questo errore dopo aver modificato il mio modello (prima il codice) come segue:

public DateTime? DateCreated

per

public DateTime DateCreated

Le righe presenti con valore null in DateCreated hanno causato questo errore. Quindi ho dovuto usare manualmente l' istruzione SQL UPDATE per inizializzare il campo con un valore standard.

Un'altra soluzione potrebbe essere una specifica del valore predefinito per il file.


3

Nel mio caso, nell'inizializzatore della classe che stavo usando nella tabella del database, non stavo impostando alcun valore predefinito sulla mia proprietà DateTime, risultando quindi nel problema spiegato nella risposta di @Andrew Orsich. Quindi ho appena reso nulla la proprietà. O avrei potuto anche darlo DateTime.Now nel costruttore. Spero che aiuti qualcuno.


3

Sembra che tu stia utilizzando un framework di entità. La mia soluzione era quella di passare tutte le colonne datetime a datetime2 e utilizzare datetime2 per eventuali nuove colonne, in altre parole fare in modo che EF utilizzasse datetime2 per impostazione predefinita. Aggiungi questo al metodo OnModelCreating nel tuo contesto:

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

Che otterrà tutto il DateTime e DateTime? proprietà su tutte le entità nel modello.


2

Ho avuto lo stesso problema, sfortunatamente, ho due proprietà DateTime sul mio modello e una proprietà DateTime è nulla prima di fare SaveChanges.

Quindi assicurati che il tuo modello abbia il valore DateTime prima di salvare le modifiche o rendilo nullable per prevenire errori:

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

Quindi questo risolve il mio problema, è una questione di assicurarsi che la data del modello sia corretta prima di persistere nel database:

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

2

Se si utilizza Entity Framework versione> = 5, l'applicazione dell'annotazione [DatabaseGenerated (DatabaseGeneratedOption.Computed)] alle proprietà DateTime della classe consentirà al trigger della tabella del database di svolgere il proprio compito inserendo le date per la creazione e l'aggiornamento dei record senza causare il tuo codice Entity Framework da imbavagliare.

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

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

Questo è simile alla sesta risposta, scritta da Dongolo Jeno e curata da Gille Q.


1

Inoltre, se non conosci parte del codice in cui si è verificato un errore, puoi profilare un'esecuzione sql "errata" usando il profiler sql integrato in mssql.

Il parametro datetime errato mostrerà qualcosa del genere:

cattivo param


1

Questo problema si verifica in genere quando si tenta di aggiornare un'entità. Ad esempio, hai un'entità che contiene un campo chiamato DateCreatedche è [Obbligatorio] e quando inserisci un record, non viene restituito alcun errore ma quando vuoi aggiornare quella particolare entità, ottieni

Errore di conversione fuori intervallo datetime2.

Ora ecco la soluzione:

Nella tua vista di modifica, vale edit.cshtmla dire per gli utenti MVC tutto ciò che devi fare è aggiungere un campo modulo nascosto DateCreatedproprio sotto il campo nascosto per la chiave primaria dei dati di modifica.

Esempio:

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

Aggiungendo questo alla tua vista di modifica, non avrai mai quell'errore che ti assicuro.


1

Devi abilitare il valore null per la tua variabile data:

 public Nullable<DateTime> MyDate{ get; set; }

0

Prova a rendere nulla la tua proprietà.

    public DateTime? Time{ get; set; }

Ha funzionato per me.


0

Se hai accesso al DB, puoi cambiare il tipo di colonna DB da datetime a datetime2 (7) invierà comunque un oggetto datetime e verrà salvato


0

Il modello dovrebbe avere datetime nullable. Il metodo suggerito in precedenza per recuperare l'oggetto che deve essere modificato dovrebbe essere usato al posto di ApplyPropertyChanges. Nel mio caso avevo questo metodo per salvare il mio oggetto:

public ActionResult Save(QCFeedbackViewModel item)

E poi in servizio, recupero usando:

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

Il codice completo del servizio è il seguente:

 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();

0

[Risolto] In Entity Framework Code In primo luogo (il mio caso) sto solo cambiando DateTimeper DateTime?risolvere il mio problema.

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

0

Errore: la conversione di un tipo di dati datetime2 in un tipo di dati datetime ha prodotto un valore fuori intervallo.

Questo errore si è verificato a causa di NOT assegnato alcun valore a una colonna di data NOT NULL in SQL DB mediante EF ed è stato risolto assegnando lo stesso.

Spero che questo ti aiuti!


0

Ho riscontrato questo problema quando ho creato le mie lezioni dall'approccio Database First. Risolto usando semplicemente Convert.DateTime (dateCausingProblem) In effetti, prova sempre a convertire i valori prima di passare, ti salva da valori imprevisti.


0

devi abbinare il formato di input del tuo campo data al formato entità richiesto che è aaaa / mm / gg


1
Esistono altre risposte che forniscono la domanda del PO e sono state pubblicate qualche tempo fa. Quando invio una risposta, vedi: Come posso scrivere una buona risposta? , assicurati di aggiungere una nuova soluzione o una spiegazione sostanzialmente migliore, soprattutto quando rispondi a domande precedenti.
help-info.de
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.