Die Konvertierung eines Datetime2-Datentyps in einen Datetime-Datentyp führte zu einem Wert außerhalb des Bereichs

174

Ich habe den folgenden Code in meinem 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");
}

Und dies ist die Ansicht für die Edit-Methode:

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

<% } %>

Wenn ich auf die Schaltfläche "Senden" klicke, wird folgende Fehlermeldung angezeigt: {"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."}Irgendwelche Ideen, wo das Problem liegt? Ich gehe davon aus, dass die Bearbeitungsmethode versucht, den in der Datenbank veröffentlichten Wert auf den bearbeiteten Wert zu aktualisieren, aber aus irgendeinem Grund gefällt es ihm nicht ... Obwohl ich nicht verstehe, warum das Datum betroffen ist, da es in der nicht erwähnt wird Controller-Methode zum Bearbeiten?

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

Antworten:

166

Das Problem besteht darin, dass Sie ein Modellobjekt verwenden ApplyPropertyChanges, das nur mit Daten im Formular (Überschrift, Story und Bild) gefüllt wurde. ApplyPropertyChangesWendet Änderungen auf alle Eigenschaften des Objekts an, einschließlich Ihrer nicht initialisierten DateTimeObjekte, die auf 0001-01-01 festgelegt sind und außerhalb des Bereichs von SQL Server liegen DATETIME.

Anstatt zu verwenden ApplyPropertyChanges, würde ich vorschlagen, das zu ändernde Objekt abzurufen, die spezifischen Felder zu ändern, die Ihr Formular bearbeitet, und das Objekt mit diesen Änderungen zu speichern. Auf diese Weise werden nur geänderte Felder geändert. Alternativ können Sie versteckte Eingaben auf Ihrer Seite mit den anderen ausgefüllten Feldern platzieren, aber das wäre bei gleichzeitigen Änderungen nicht sehr freundlich.

Aktualisieren:

Hier ist ein ungetestetes Beispiel für die Aktualisierung einiger Felder Ihres Objekts (dies setzt voraus, dass Sie LINQ to SQL verwenden):

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
quelle
Sehr hilfreich :) Ich habe mich gefragt, warum das Datum geändert wurde, als ich es nicht angegeben hatte. Können Sie helfen, die Edit-Methode so zu ändern, dass ApplyPropertyChanges nicht mehr verwendet wird? Da ich neu bei ASP.NET bin und im Moment nicht alles verstehe. Danke Kumpel.
Cameron
Was ist, wenn ich das Datum auf das aktuelle Datum einstellen wollte, dh. das Datum, zu dem der Artikel aktualisiert wurde? Da dies wahrscheinlich die beste Option sein wird und ich davon ausgehe, dass es mit den ApplyPropertyChanges funktionieren würde, die ich im Spiel habe.
Cameron
Siehe meine Bearbeitung (es wird davon ausgegangen, dass dies modifiedDateder Name Ihrer Immobilie ist)
Jacob
SubmitChanges funktioniert in meiner App nicht: / Ist es möglich, das story.modifiedDate = DateTime.Now;Bit meinem aktuellen Code hinzuzufügen ? Vielen Dank
Cameron
1
Dieser Fehler tritt auf, wenn wir public DateTime CreatedDate anstelle von public DateTime festlegen. CreatedDate, da DateTime nicht null sein kann, weshalb es einen Fehler außerhalb des Bereichs gibt. es mag hilfreich sein, aber es hat mein Problem gelöst.
Adnan
115

Dies ist ein häufiger Fehler, mit dem Benutzer bei der Verwendung von Entity Framework konfrontiert sind. Dies tritt auf, wenn die Entität, die der zu speichernden Tabelle zugeordnet ist, ein obligatorisches Datum / Uhrzeit-Feld hat und Sie es nicht mit einem bestimmten Wert festlegen.

Das Standardobjekt datetime wird mit dem Wert von erstellt 01/01/1000und anstelle von null verwendet. Dies wird an die Datums- / Uhrzeitspalte gesendet, die Datumswerte von nun 1753-01-01 00:00:00an, jedoch nicht vorher, enthalten kann, was zu einer Ausnahme außerhalb des Bereichs führt.

Dieser Fehler kann behoben werden, indem entweder das Datenbankfeld so geändert wird, dass es null akzeptiert, oder indem das Feld mit einem Wert initialisiert wird.

Sanjay Kumar Madhva
quelle
3
Dies ist der Fall, wenn das Datum / Uhrzeit-Feld in der Datenbank optional ist und der Wert nicht festgelegt ist. Daher ist dies kein gewöhnlicher Fehler. Dies ist eines der Probleme der EF-Architektur.
GSoft Consulting
1
Ich bin damit einverstanden, dass EF den Typ in DB sehen und entsprechend anpassen oder einen genaueren Fehler werfen oder zumindest werfen sollte. Auf der anderen Seite gefällt mir Ihre Antwort, da Sie anstelle der üblichen zwei Optionen angegeben haben - initialisieren Sie die Datei mit dem Mindestwert.
DanteTheSmith
43

DATETIMEunterstützt 1753/1/1 bis "Ewigkeit" (9999/12/31), während DATETIME2Unterstützung 0001/1/1 bis Ewigkeit.

Msdn

Antwort: Ich nehme an, Sie versuchen, DateTimemit dem Wert '0001/1/1' zu speichern . Setzen Sie einfach den Haltepunkt und debuggen Sie ihn. Wenn ja, ersetzen Sie ihn DateTimedurch nulldas normale Datum oder legen Sie es fest.

Andrew Orsich
quelle
Was lege ich aber in den Controller? Das Debuggen bringt nur den Fehler, den ich oben gepostet habe. Vielen Dank.
Cameron
scheint hier ein Fehler zu sein -> _db.SaveChanges (); Sie können Haltepunkt vor dieser Linie setzen ...
Andrew Orsich
Ja, habe es getan. Dann heißt es, dass es sich um einen Fehler in den SaveChanges handelt, also schaue ich mir die InnerException an und es heißt, dass dies auf den Fehler zurückzuführen ist, der veröffentlicht wurde. Das ist also der Fehler!
Cameron
Haben Sie den DateTime-Wert vor _db.SaveChanges () überprüft? hieß? Es sollte großartig sein als '1753/1/1'.
Andrew Orsich
Der ursprüngliche Artikel-Datumswert ist {18/10/2009 00:00:00} und der ArticleToEdit-Datumswert ist {01/01/0001 00:00:00}. Es scheint also, dass versucht wird, das Datum auf den 1. von allem zu ändern, was nicht ist Ich will nicht, will aber nicht erklären, warum es den Fehler auslöst, da das Format das gleiche ist, oder?
Cameron
14

Dieser machte mich verrückt. Ich wollte vermeiden, eine nullbare Datumszeit ( DateTime?) zu verwenden. Ich hatte auch nicht die Möglichkeit, den datetime2-Typ von SQL 2008 zu verwenden ( modelBuilder.Entity<MyEntity>().Property(e => e.MyDateColumn).HasColumnType("datetime2");).

Ich entschied mich schließlich für Folgendes:

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
quelle
10

Sie können dieses Problem auch beheben, indem Sie es zum Modell hinzufügen (Entity Framework-Version> = 5).

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

Wenn Sie eine Spalte haben, die datetime ist und null zulässt, wird dieser Fehler angezeigt. Ich empfehle, einen Wert festzulegen, der vor .SaveChanges () an das Objekt übergeben wird.

Patrick
quelle
5

Ich habe diesen Fehler erhalten, nachdem ich mein Modell (Code zuerst) wie folgt geändert habe:

public DateTime? DateCreated

zu

public DateTime DateCreated

Vorhandene Zeilen mit dem Nullwert in DateCreated haben diesen Fehler verursacht. Daher musste ich die SQL UPDATE-Anweisung manuell verwenden, um das Feld mit einem Standardwert zu initialisieren.

Eine andere Lösung könnte die Angabe des Standardwerts für die Datei sein.

Aleksandr Khomenko
quelle
3

In meinem Fall habe ich im Initialisierer der Klasse, die ich in der Datenbanktabelle verwendet habe, keinen Standardwert für meine DateTime-Eigenschaft festgelegt, was zu dem in der Antwort von @Andrew Orsich erläuterten Problem führte. Also habe ich die Eigenschaft einfach auf null gesetzt. Oder ich hätte es auch DateTime.Now im Konstruktor geben können. Hoffe es hilft jemandem.

StinkyCat
quelle
3

Es sieht so aus, als würden Sie das Entity Framework verwenden. Meine Lösung bestand darin, alle datetime-Spalten auf datetime2 umzustellen und datetime2 für alle neuen Spalten zu verwenden. Mit anderen Worten, EF sollte standardmäßig datetime2 verwenden. Fügen Sie dies der OnModelCreating-Methode in Ihrem Kontext hinzu:

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

Das wird alle DateTime und DateTime bekommen? Eigenschaften für alle Entitäten in Ihrem Modell.

Ogglas
quelle
2

Ich hatte das gleiche Problem, leider habe ich zwei DateTime-Eigenschaften in meinem Modell und eine DateTime-Eigenschaft ist null, bevor ich SaveChanges ausführe.

Stellen Sie daher sicher, dass Ihr Modell den DateTime-Wert hat, bevor Sie Änderungen speichern, oder machen Sie es nullwertfähig, um Fehler zu vermeiden:

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

Damit ist mein Problem gelöst. Stellen Sie sicher, dass Ihr Modelldatum korrekt ist, bevor Sie in der Datenbank bleiben:

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

Wenn Sie die Entity Framework-Version> = 5 verwenden und die Annotation [DatabaseGenerated (DatabaseGeneratedOption.Computed)] auf Ihre DateTime-Eigenschaften Ihrer Klasse anwenden, kann der Trigger der Datenbanktabelle Daten für die Datensatzerstellung und Datensatzaktualisierung eingeben, ohne dies zu verursachen Ihr Entity Framework-Code zum Würgen.

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

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

Dies ähnelt der 6. Antwort, die von Dongolo Jeno geschrieben und von Gille Q herausgegeben wurde.

Jim Kay
quelle
1

Wenn Sie keinen Teil des Codes kennen, in dem ein Fehler aufgetreten ist, können Sie die "schlechte" SQL-Ausführung mit dem in mssql integrierten SQL-Profiler profilieren.

Ein schlechter datetime-Parameter zeigt ungefähr Folgendes an:

schlechter param

Nigrimmist
quelle
1

Dieses Problem tritt normalerweise auf, wenn Sie versuchen, eine Entität zu aktualisieren. Zum Beispiel haben Sie eine Entität , die ein Feld mit dem Namen enthält , DateCreateddie ist [Erforderlich] und wenn Sie Datensatz einfügen, wird kein Fehler zurückgegeben , aber wenn Sie aktualisieren möchten , dass bestimmte Entität, die Sie erhalten die

datetime2 Konvertierung außerhalb des Bereichs Fehler.

Hier ist die Lösung:

In Ihrer Bearbeitungsansicht, dh edit.cshtmlfür MVC-Benutzer, müssen Sie DateCreatedlediglich ein ausgeblendetes Formularfeld für Ihr direkt unter dem ausgeblendeten Feld für den Primärschlüssel der Bearbeitungsdaten hinzufügen .

Beispiel:

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

Wenn Sie dies zu Ihrer Bearbeitungsansicht hinzufügen, wird dieser Fehler niemals auftreten, wie ich Ihnen versichere.

Aduwu Joseph
quelle
1

Sie müssen den Nullwert für Ihre Datumsvariable aktivieren:

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

Versuchen Sie, Ihre Eigenschaft auf Null zu setzen.

    public DateTime? Time{ get; set; }

Hat für mich gearbeitet.

typhon04
quelle
0

Wenn Sie Zugriff auf die Datenbank haben, können Sie den DB-Spaltentyp von datetime in datetime2 (7) ändern. Es wird weiterhin ein datetime-Objekt gesendet und es wird gespeichert

Sergiu Mindras
quelle
0

Das Modell sollte eine nullbare Datumszeit haben. Die zuvor vorgeschlagene Methode zum Abrufen des zu ändernden Objekts sollte anstelle von ApplyPropertyChanges verwendet werden. In meinem Fall hatte ich diese Methode, um mein Objekt zu speichern:

public ActionResult Save(QCFeedbackViewModel item)

Und dann im Dienst rufe ich ab mit:

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

Der vollständige Servicecode lautet wie folgt:

 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
quelle
0

[Gelöst] In Entity Framework Code Zuerst (mein Fall) wird nur geändert DateTime, DateTime?um mein Problem zu lösen.

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

Fehler: Die Konvertierung eines Datetime2-Datentyps in einen Datetime-Datentyp führte zu einem Wert außerhalb des Bereichs.

Dieser Fehler trat aufgrund von auf nicht einen beliebigen Wert gegen einen NOT NULL Datumsspalte in SQL DB mit EF Zuweisung und wurde durch die Zuordnung der gleichen aufgelöst.

Hoffe das hilft!

user2964808
quelle
0

Ich habe dieses Problem beim Erstellen meiner Klassen aus dem Database First-Ansatz. Mit einfach Convert.DateTime (dateCausingProblem) gelöst. Versuchen Sie immer, Werte vor dem Übergeben zu konvertieren. Sie werden vor unerwarteten Werten bewahrt.

Ansar nisar Gill
quelle
0

Sie müssen das Eingabeformat Ihres Datumsfelds an das erforderliche Entitätsformat anpassen, das JJJJ / MM / TT lautet

marc
quelle
1
Es gibt andere Antworten, die die Frage des OP stellen, und sie wurden vor einiger Zeit veröffentlicht. Wenn Sie eine Antwort veröffentlichen, lesen Sie: Wie schreibe ich eine gute Antwort? Bitte stellen Sie sicher, dass Sie entweder eine neue Lösung oder eine wesentlich bessere Erklärung hinzufügen, insbesondere wenn Sie ältere Fragen beantworten.
help-info.de