Ich verwende die mit Entity Framework 4.1 eingeführten APIs DbContext und Code First.
Das Datenmodell verwendet grundlegende Datentypen wie string
und DateTime
. Die einzige Datenanmerkung, die ich in einigen Fällen verwende, ist [Required]
, aber das gilt nicht für eine der DateTime
Eigenschaften. Beispiel:
public virtual DateTime Start { get; set; }
Die DbContext-Unterklasse ist ebenfalls einfach und sieht folgendermaßen aus:
public class EventsContext : DbContext
{
public DbSet<Event> Events { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Event>().ToTable("Events");
}
}
Der Initialisierer setzt die Daten im Modell entweder in diesem oder im nächsten Jahr auf sinnvolle Werte.
Wenn ich jedoch den Initialisierer ausführe, wird folgende Fehlermeldung angezeigt context.SaveChanges()
:
Die Konvertierung eines Datetime2-Datentyps in einen Datetime-Datentyp führte zu einem Wert außerhalb des Bereichs. Die Anweisung wurde beendet.
Ich verstehe nicht, warum das überhaupt passiert, weil alles so einfach ist. Ich bin mir auch nicht sicher, wie ich das beheben soll, da keine edmx-Datei zum Bearbeiten vorhanden ist.
Irgendwelche Ideen?
quelle
Antworten:
Sie müssen sicherstellen, dass Start größer oder gleich SqlDateTime.MinValue (1. Januar 1753) ist - standardmäßig ist Start gleich DateTime.MinValue (1. Januar 0001).
quelle
Einfach. Setzen Sie zuerst in Ihrem Code den Typ von DateTime auf DateTime?. Sie können also mit dem nullbaren DateTime-Typ in der Datenbank arbeiten. Entitätsbeispiel:
quelle
In einigen Fällen
DateTime.MinValue
(oder gleichwertigdefault(DateTime)
) wird ein unbekannter Wert angegeben.Diese einfache Erweiterungsmethode kann bei solchen Situationen helfen:
Verwendung:
quelle
Sie können das Feld auf Null setzen, wenn dies Ihren spezifischen Modellierungsproblemen entspricht. Ein Nulldatum wird nicht zu einem Datum gezwungen, das nicht im Bereich des SQL DateTime-Typs liegt, wie dies bei einem Standardwert der Fall wäre. Eine andere Möglichkeit besteht darin, explizit einem anderen Typ zuzuordnen, möglicherweise mit,
quelle
Obwohl diese Frage ziemlich alt ist und es bereits gute Antworten gibt, dachte ich, ich sollte noch eine hinzufügen, die 3 verschiedene Ansätze zur Lösung dieses Problems erklärt.
1. Ansatz
Map Explizit
DateTime
Eigenschaftpublic virtual DateTime Start { get; set; }
aufdatetime2
Spalte in der Tabelle in entspricht. Weil EF es standardmäßig zuordnetdatetime
.Dies kann durch fließende API- oder Datenanmerkungen erfolgen.
Fließende API
In der DbContext-Klasse überschreiben
OnModelCreating
und konfigurieren Sie die EigenschaftStart
(aus Erklärungsgründen ist sie eine Eigenschaft der EntityClass-Klasse).Datenanmerkung
2. Ansatz
Initialisieren Sie
Start
im EntityClass-Konstruktor auf einen Standardwert. Dies ist gut, als ob aus irgendeinem Grund der Wert vonStart
nicht festgelegt wird, bevor die Entität im Datenbankstart gespeichert wird. Dies hat immer einen Standardwert. Stellen Sie sicher, dass der Standardwert größer oder gleich SqlDateTime.MinValue ist (vom 1. Januar 1753 bis 31. Dezember 9999).3. Ansatz
Machen Sie
Start
vom Typ nullableDateTime
-note?
nachDateTime
-Weitere Erklärungen finden Sie in diesem Beitrag
quelle
Wenn Ihre
DateTime
Eigenschaften in der Datenbank nullwertfähig sind, müssen Sie sieDateTime?
für die zugeordneten Objekteigenschaften verwenden. Andernfalls wird EFDateTime.MinValue
für nicht zugewiesene Werte übergeben, die außerhalb des Bereichs liegen, den der SQL-Datetime-Typ verarbeiten kann.quelle
Meine Lösung bestand darin, alle datetime-Spalten auf datetime2 umzustellen und datetime2 für alle neuen Spalten zu verwenden. Mit anderen Worten, lassen Sie EF standardmäßig datetime2 verwenden. Fügen Sie dies der OnModelCreating-Methode in Ihrem Kontext hinzu:
Das wird alle DateTime und DateTime bekommen? Eigenschaften für alle Ihre Entitäten.
quelle
Initialisieren Sie die Start-Eigenschaft im Konstruktor
Dies funktionierte für mich, als ich versuchte, mithilfe von Code First einige neue Felder zur Benutzertabelle (AspNetUsers) des ASP .Net Identity Framework hinzuzufügen. Ich habe den Class - ApplicationUser in IdentityModels.cs aktualisiert und ein Feld lastLogin vom Typ DateTime hinzugefügt.
quelle
Basierend auf der Antwort von user @ andygjp ist es besser, wenn Sie die Basismethode überschreiben
Db.SaveChanges()
und eine Funktion hinzufügen, um jedes Datum zu überschreiben, das nicht zwischen SqlDateTime.MinValue und SqlDateTime.MaxValue liegt.Hier ist der Beispielcode
Entnommen aus dem Kommentar von user @ sky-dev unter https://stackoverflow.com/a/11297294/9158120
quelle
Ich hatte das gleiche Problem und in meinem Fall habe ich das Datum auf new DateTime () anstelle von DateTime.Now gesetzt
quelle
In meinem Fall geschah dies, als ich eine Entität verwendete und die SQL-Tabelle den Standardwert datetime == getdate () hatte. Also, was ich getan habe, um einen Wert für dieses Feld festzulegen.
quelle
Ich verwende zuerst die Datenbank. Als mir dieser Fehler auftrat, bestand meine Lösung darin, ProviderManifestToken = "2005" in der edmx-Datei zu erzwingen (wodurch die Modelle mit SQL Server 2005 kompatibel wurden). Ich weiß nicht, ob für Code First etwas Ähnliches möglich ist.
quelle
Eine Zeile behebt dies:
Also habe ich in meinem Code hinzugefügt:
Das Hinzufügen dieser einen Zeile zur DBContext-Unterklasse überschreibt den Abschnitt void OnModelCreating.
quelle
In meinem Fall schlugen meine Tests nach einigen Umgestaltungen in EF6 mit derselben Fehlermeldung wie das Originalposter fehl, aber meine Lösung hatte nichts mit den DateTime-Feldern zu tun.
Beim Erstellen der Entität fehlte mir nur ein erforderliches Feld. Nachdem ich das fehlende Feld hinzugefügt hatte, verschwand der Fehler. Meine Entität hat zwei DateTime? Felder, aber sie waren nicht das Problem.
quelle