Ich speichere ein Cart-Objekt in der Datenbank mit einer nullbaren Datetime. Dies ist der Fehler, den ich bekomme:
Die Konvertierung eines Datetime2-Datentyps in einen Datetime-Datentyp ergab einen Wert außerhalb des Bereichs.
Es gibt ziemlich viele Stackoverflow-Beiträge, die Korrekturen für dieses Problem dokumentieren. Wenn Code jedoch zuerst die Datenbank erstellt, erstellt er das Feld als DateTime (Nullen zulassen). Aus irgendeinem Grund versucht Code jedoch zuerst, ein DateTime2-Feld einzufügen.
Ich wundere mich, warum EF das Feld in einer Richtung erstellt, aber mit einem anderen Typ für dasselbe Feld einfügt.
Dies ist das Domänenobjekt:
%Vor%Das Modell:
%Vor% Also sind sowohl OpeningDateUtc
als auch ClosingDateUtc
vom Typ DateTime?.
So wird die Datenbank zuerst mit dem EF-Code generiert:
Die OpeningDateUtc
und ClosingDateUtc
werden als Nullable DateTime Feld erstellt.
Warum also, wenn ich mit IDBContext.SaveChanges()
speichere, lautet das für die Abfrage generierte SQL:
Der interessante Teil ist @4 datetime2(7),@5 datetime2(7)
.
Ich verstehe, dass ich dieses Problem beheben konnte, indem ich ein .HasColumnType("datetime2")
zur Warenkorbkarte hinzufügte, aber es beantwortet nicht, warum EF5 (und wahrscheinlich ältere Versionen) sie auf nullable datetime setzen.
Der DateTime
-Typ in .NET hat den gleichen Bereich und die gleiche Genauigkeit wie datetime2
in SQL Server. Wenn EF eine Spalte datetime
oder datetime2
in SQL Server einfügt oder aktualisiert, wird die Modelleigenschaft in den Typ konvertiert, der den gesamten Bereich von DateTime
in .NET enthalten kann, also datetime2
. Die Konvertierung in datetime
würde fehlschlagen, wenn die DateTime
-Eigenschaft nicht im Bereich von datetime
in SQL Server liegt.
Das Problem, das die Ausnahme verursacht, sind übrigens nicht die zwei Nullable OpeningDateUtc
und ClosingDateUtc
Spalten, sondern der CreatedOnUtc
Wert, der '0001-01-01 00:00:00'
in Ihrem SQL Snippet ist, dh CreatedOnUtc
ist anscheinend nicht initialisiert in Ihrer Modelleinheit. Das früheste Datum, das datetime
in SQL Server speichern kann, ist im Jahr 1750, also passt Jahr 0001 nicht in den Typ (aber es würde in datetime2
passen).
Die Lösung besteht also darin, CreatedOnUtc
auf einen gültigen datetime
Wert zu setzen oder - wie Sie wissen - die Typen als datetime2
in Ihrem Mapping zu definieren.
Aber ich stimme zu, es würde weniger Verwirrung geben, wenn EF DateTime
Eigenschaften standardmäßig auf datetime2
abbildet.
Das EF Team hat diesen speziellen Punkt während eines der Design-Meetings besprochen. Die Entscheidung war, das aktuelle Verhalten so zu lassen, wie es ist. Hier sind die Meeting-Notizen , die Ihnen mehr bieten können Kontext.
Tags und Links entity-framework datetime ef-code-first datetime2