'datetime2' Fehler beim Verwenden von Entity Framework in VS 2010 .net 4.0

Erhalten Sie diesen Fehler:

System.Data.SqlClient.SqlException: Die Umwandlung eines Datetime2-datatyps in einen Datetime-datatyp führte zu einem Out-of-Range-Wert.

Meine Entität belegt alle Zeilen bis zu den DB-objecten.

Ich habe nur einen einzigen Hinweis auf diesen Fehler über Google gefunden:

Google Ergebnis

Nachdem ich das gelesen habe, erinnere ich mich, dass wir 2 Felder hinzugefügt haben und dann das Entity-model von VS 2010 aktualisiert haben. Ich bin mir nicht sicher, was er mit "Handcodierung" der Unterschiede meint. Ich sehe keinen

Alles, was ich im Code tue, bevölkert das Entity-object und dann das memoryn. (Ich auch bevölkern die neuen Felder in Code) Ich bevölkert das datesfeld mit DateTime.Now ..

Der wichtige Teil des Codes ist das: ctx.SaveChanges(SaveOptions.AcceptAllChangesAfterSave);

Die database ist SQL server 2008.

Gedanken?

Der Rest des Fehlers:

unter System.Data.Mapping.Update.Internal.UpdateTranslator.Update (IEntityStateManager stateManager, IEntityAdapter-Adapter) bei System.Data.EntityClient.EntityAdapter.Update (IEntityStateManager entityCache) unter System.Data.Objects.ObjectContext.SaveChanges (SaveOptions-Optionen) bei SafariAdmin.Site.WebServices.SpeciesPost.SaveOrUpdateSpecies (String sid, String fieldName, String authToken) in SpeciesPost.svc.cs: Zeile 58 bei SafariAdmin.TestHarness.Tests.Site.WebServices.SpeciesPostSVC_Tester.SaveNewSpecies () in SpeciesPostSVC_Tester.cs: Zeile 33 –SqlException bei System.Data.SqlClient.SqlConnection.OnError (SqlException exception, Boolean breakConnection) bei System.Data.SqlClient.SqlInternalConnection.OnError (SqlException exception, Boolean breakConnection) bei System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning () bei System.Data.SqlClient.TdsParser.Run (RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateO bj) bei System.Data.SqlClient.SqlDataReader.ConsumeMetaData () bei System.Data.SqlClient.SqlDataReader.get_MetaData () bei System.Data.SqlClient.SqlCommand.FinishExecuteReader (SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) bei System.Data .SqlClient.SqlCommand.RunExecuteReaderTds (CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) bei System.Data.SqlClient.SqlCommand.RunExecuteReader (CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String-Methode, DbAsyncResult Ergebnis) bei System.Data. SqlClient.SqlCommand.RunExecuteReader (CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String-Methode) bei System.Data.SqlClient.SqlCommand.ExecuteReader (CommandBehavior Verhalten, String-Methode) bei System.Data.SqlClient.SqlCommand.ExecuteDbDataReader (CommandBehavior Verhalten) bei System.Data.Common.DbCommand.ExecuteReader (CommandBehavior Verhalten) bei System.Data.Mapping.Update.Internal.DynamicUpdateComma nd.Execute (UpdateTranslator-Übersetzer, EntityConnection-Verbindung, dictionary 2 identifierValues, List 1 generatedValues) bei System.Data.Mapping.Update.Internal.UpdateTranslator.Update (IEntityStateManager stateManager, IEntityAdapter-Adapter)

Entity Framework behandelt alle data als Datetime2, also, wenn Ihre Felder in der database Datetime sind, könnte dies ein Problem sein. Wir hatten das gleiche Problem hier, und von dem, was wir fanden, bevölkern alle datesfelder und das Ändern des datatyps, sind die meisten commom Lösungen

Wenn Sie Code First verwenden, müssen Sie jede optionale DateTime Eigenschaft als DateTime? oder Nullable<DateTime> . Unset DateTime objecte können Probleme verursachen.

Wenn die Eigenschaft in der database nullable und ein Standard DateTime in Code (nicht DateTime? ) DateTime? , sendet ADO.NET einen Insert-Befehl mit einem date von 0001-01-01 (nicht NULL ), aber der minimale SQL DateTime-Wert ist 1753 -01-01, was einen Fehler verursacht. Wenn Ihre DateTime Eigenschaft im Code nullable ist (zB DateTime? Oder Nullable<DateTime> ), wird der Insert-Befehl versuchen, ein NULL anstelle eines Out-of-Range-dates einzufügen.

Verwenden Sie dieses SQL-Skript, um alle Spalten von datetime zu datetime2 zu datetime2 . Es überspringt alle Tische enthält 'aspnet' für Ihre Bequemlichkeit.

 DECLARE @SQL AS NVARCHAR(1024) DECLARE @TBL AS NVARCHAR(255) DECLARE @COL AS NVARCHAR(255) DECLARE @NUL AS BIT DECLARE CUR CURSOR FAST_FORWARD FOR SELECT SCHEMA_NAME(t.schema_id)+'.'+t.name, c.name, c.is_nullable FROM sys.tables AS t JOIN sys.columns c ON t.object_id = c.object_id JOIN information_schema.columns i ON i.TABLE_NAME = t.name AND i.COLUMN_NAME = c.name WHERE i.data_type = 'datetime' and t.name not like '%aspnet%' ORDER BY t.name, c.name OPEN CUR FETCH NEXT FROM CUR INTO @TBL, @COL, @NUL WHILE @@FETCH_STATUS = 0 BEGIN SELECT @SQL = 'ALTER TABLE ' + @TBL + ' ALTER COLUMN [' + @COL + '] datetime2' + (CASE WHEN @NUL=1 THEN '' ELSE ' NOT' END) + ' NULL;' EXEC sp_executesql @SQL FETCH NEXT FROM CUR INTO @TBL, @COL, @NUL END CLOSE CUR; DEALLOCATE CUR; 

Für mich geht das!

Eine weitere mögliche Lösung besteht darin, den sql-Spaltentyp des Feldes auf datetime2 zu setzen. dies kann mit fluentapi erfolgen.

 Property(x => x.TheDateTimeField) .HasColumnType("datetime2"); 

Hinweis: Dies ist eine Lösung für SQL server 2008 nach oben, da datetime2 für SQL server 2005 oder höher nicht verfügbar ist.

Ich hatte das gleiche Problem und löse es, indem ich das Attribut [Column(TypeName = "datetime2")] auf verwandte properties, wie unten Beispiel:

  [Column(TypeName = "datetime2")] public DateTime? PropertyName { get; set; } 

Ich weiß, dass es eine alte Frage ist, aber wie ich hier gegoogelt habe, könnte jemand anderes dasselbe machen 😉 Für diejenigen, die sich von DateTime zu DateTime2 ändern, ist keine Option (wie bei SQL2005-Nutzern), denke ich in den meisten Fällen vernünftiger zu (DateTime)System.Data.SqlTypes.SqlDateTime.MinValue Felder leer gelassen mit so etwas wie (DateTime)System.Data.SqlTypes.SqlDateTime.MinValue
und nicht mit DateTime.now, da es einfacher ist, es als "Pseudo-Null" -Wert zu erkennen (und wenn es nötig ist, es in eine echte Null in einer Teilklasse des Vaterobjekts umzuwandeln)

Bei der Verwendung von Entity-Framework-Code zuerst, deklarieren Sie es wie folgt:

 public Nullable<System.DateTime> LastLogin { get; set; } 

Gibt es ModifiedTime-Eigenschaft in deiner Entität, die nur auf der databaseseite aktualisiert wird? Wenn ja, müssen Sie DatabaseGeneratedOption.Computed (für EF CodeFirst) verwenden. Besuchen Sie auch diese https://stackoverflow.com/a/9508312/1317263

Vielen Dank.

Wir hatten das gleiche Problem. Dies hängt mit der mssql-Version zusammen. Wir haben es für alle unsere Version mit dieser Methode gemacht.

Öffnen Sie Ihre Edmx-file mit einem XML-Editor Finden Sie diese Zeile am Anfang Ihrer file

 <Schema Namespace="XXXXX.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2008" 

Ersetzen Sie die 2008 bis 2005 memoryn Sie Ihre file, kompilieren Sie das Projekt.

Hoffe, das wird jemand anderem im Futur helfen.

Ich habe diese Lösung nur mit einer dbfirst approche ausprobiert.

Was auch immer in eine datetime passt in einen datetime2 datatyp passen, umgekehrt das ist nicht der Fall, können Sie ein date von Januar 1500 in einem datetime2 datatyp, aber datetime nur geht zurück zu 1753, eine datetime2 Spalte kann zurück gehen alle path zum Jahr 1. Ich würde überprüfen, was die min date, dass Sie vorbei sind, und wenn Ihre Tabellen datetime2 oder datetime datatyp Spalten haben

Nach dem Versuch, dieses Problem für mehrere Tage zu lösen, habe ich DateTime? als der datatyp in meinem model mit Entity Framework Code-First statt DateTime .

Stellen Sie sicher, dass beim Einfügen / Aktualisieren keine der Nicht-Nullfelder im DB (datetime) ausgelassen wird. Ich hatte den gleichen Fehler und beim Einfügen von Werten in diese datetime Felder wurde das Problem getriggers. Dies geschieht, wenn die nicht null datetime Felder keinen richtigen Wert zugewiesen sind.

Ich hatte das gleiche Problem in meiner ASP.Net MVC Anwendung.

Es gab zwei modelklassen in meiner Anwendung, die DateTime-properties hatten.

bei der Untersuchung bemerkte ich, dass die DateTime-Eigenschaft eines models nullable war, dh, um es date der Geburt optionale Eigenschaft zu machen

das andere model hatte DateTime-Eigenschaft mit erforderlicher data-Annotation (Fehler beim memoryn dieses models)

meine App ist Code zuerst, so dass ich das Problem getriggers, indem Sie datatyp als DateTime2

 [Column(TypeName="datetime2")] 

dann lief ich die Migration auf Paket-Manager-Konsole.

Einfach. Geben Sie auf Ihrem Code zuerst die Art von DateTime auf DateTime ein ?. So können Sie mit nullable DateTime-Typ in der database arbeiten.

Dies folgt aus StepanZ Antwort … Ich habe diesen Fehler bei der Verwendung von Entity Framework Code First mit AutoMapper .

Beim Einrichten des AutoMapping wir createddt , updateddt , createdby und updatedby Feldern, die automatisch in unserer public override int SaveChanges() function gesetzt werden. Wenn Sie dies tun, müssen Sie sicherstellen, dass diese Felder von AutoMapper ignoriert werden, andernfalls wird die database mit null für diese Felder aktualisiert, wenn sie nicht aus der View geliefert werden.

Meine Frage war, dass ich die Quelle und das Ziel um den falschen path gelegt hatte, also versuche, die Felder bei der Einstellung des ViewModel zu ignorieren, anstatt bei der Einstellung des Model .

Die Mapping sah so aus, als ich diesen Fehler erhielt (Anmerkung: die cfg.CreateMap<Source, Destination>() in der zweiten Zeile ist das Mapping des Model auf das ViewModel und das Setzen der Ignore() )

 cfg.CreateMap<EventViewModel, Event>(); cfg.CreateMap<Event, EventViewModel>() .ForMember(dest => dest.CreatedBy, opt => opt.Ignore()) .ForMember(dest => dest.CreatedDt, opt => opt.Ignore()) .ForMember(dest => dest.UpdatedBy, opt => opt.Ignore()) .ForMember(dest => dest.UpdatedDt, opt => opt.Ignore()); 

Die Quelle und das Ziel sollten für eine Zuordnung von ViewModel zu Model ignoriert werden (Hinweis: Der untenstehende Code ist korrekt, wo das Ignore() gegen die Zuordnung für das ViewModel zum Model )

 cfg.CreateMap<Event, EventViewModel>(); cfg.CreateMap<EventViewModel, Event>() .ForMember(dest => dest.CreatedBy, opt => opt.Ignore()) .ForMember(dest => dest.CreatedDt, opt => opt.Ignore()) .ForMember(dest => dest.UpdatedBy, opt => opt.Ignore()) .ForMember(dest => dest.UpdatedDt, opt => opt.Ignore()); 

Zwei Lösungen:

  • Deklariere die properties in deiner class wie unten und mache eine Update-database:

     public DateTime? MyDate {get; set;} 
  • Oder legen Sie ein date für die Eigenschaft in der Seed-Methode fest, die die database füllt, keine Notwendigkeit der Update-database:

     context.MyClass.AddOrUpdate(y => y.MyName,new MyClass { MyName = "Random", MyDate= DateTime.Now })