Entity Framework und SqlDateTime Überlauf Best Practices
-
30-09-2019 - |
Frage
System.DateTime
kann ein breiteres Spektrum von Werten als SQL Server Datetime nehmen. Daher gibt es Klasse System.Data.SqlTypes.SqlDateTime
die später welche imitiert.
Folglich hätte ich erwartet, dass Entity Framework SqlDateTime zu wählen, aber es kam nicht.
Also meine Fragen sind ...
Was sind die besten Praktiken, um sicherzustellen, dass Ihre Datetime-Werte nicht zu Problemen führen, wenn Sie versuchen, sie zu Ihrer Datenbank speichern?
Gibt es eine Möglichkeit EF zwingen SqlDateTime zu benutzen?
Lösung
Es gibt eine Reihe von Dingen, die Sie tun können:
-
Wenn Sie SQL Server 2008 oder höher verwenden, können Sie die
DATE
oderDATETIME2
Datentypen in der Datenbank verwenden, die den gleichen Zeitraum wie .NET derDateTime
bieten -
Wenn Sie nicht diese neuen Datentypen verwenden können, wird es an Ihnen, einige Kontrollen / Validierung auf Datumsfelder zu behandeln, bevor die Dinge in den persistenten Speicher gespeichert werden. EF
EntityObject
bietet viele Möglichkeiten, um Wasserhahn in den Prozess der Validierung und Objekte Sparend - ein Ansatz wählen, dass die Arbeiten für Sie
Andere Tipps
Genauer gesagt, versuchen Sie dies: http://www.vfstech.com/?p=111
Vielleicht ist das ein alter Thread, aber ich werde meine Erkenntnisse zu diesem Thema für die andere schreiben:
Lassen Sie uns sagen, dass wir dev env: EF 5, CodeFirst, SQLCE 4.0:
public abstract class Entity : IEntity, IEquatable<Entity>
{
public virtual int Id { get; protected set; }
public virtual DateTime LastModified { get; set; }
[DataType(DataType.Date)]
public virtual DateTime CreatedOn { get; set; }
[DataType(DataType.DateTime)]
public virtual DateTime CreatedOn2 { get; set; }
[DataType(DataType.Time)]
public virtual DateTime CreatedOn3 { get; set; }
public virtual DateTime CreatedOn4 { get; set; }
}
mit einem solchen benutzerdefinierte Zuordnung:
public EntityMapping()
{
HasKey(e => e.Id);
Property(e => e.Id);
Property(e => e.LastModified).IsRequired().IsConcurrencyToken();
Property(e => e.CreatedOn).IsRequired();
Property(e => e.CreatedOn2).IsRequired();
Property(e => e.CreatedOn3).IsRequired();
Property(e => e.CreatedOn4).IsRequired();
}
Dies erzeugt dieser , was bedeutet, dass wir die Überlaufausnahme haben wird.
Ändern der Zuordnungen zu dieser, während immer noch mit SQL CE Arbeits 4.0:
Property(e => e.CreatedOn).IsRequired().HasColumnType("datetime2");
Property(e => e.CreatedOn2).IsRequired().HasColumnType("date");
Property(e => e.CreatedOn3).IsRequired().HasColumnType("date");
Property(e => e.CreatedOn4).IsRequired().HasColumnType("datetime2");
Gibt diesen Fehler . Die Umstellung auf SQL Server Standart 2012 scheint das Problem zu lösen (das keine Lösung sicher ist - nur für das Experiment). Das erstellte SQL Server-Schema ist diese .
Ich bin kein Experte in Sql, aber es sieht so aus mir, dass SQL CE nicht unterstützt diese Daten . das Problem mit der Entwicklung env. Überreste. Datetime kann ersetzt werden, kann aber eine Menge Refactoring hier bringen und tehere.
Beachten Sie auch, dass SqlDateTime und Datetime sind sehr unterschiedlich .
Die Lösung, die ich gut finde - für den Code und für den gesamten Projektzyklus - ist, um zwischen LocalDB und SQL standart wie oben von Stackoverflow durch einen der Links vorgeschlagen kombiniert mit benutzerdefinierten fluentApi Mapping-Einstellungen Modellerstellung oder beides entzerren.
Die Einführung individuelle Konvention in EF als Sicherheitsnetz sieht auch gut.
Wenn jemand hat eine bessere Allround-Lösung, für Code und für dev-Produktion beide, es posten.