Obtenir cette erreur:
System.Data.SqlClient.SqlException: la conversion d'un type de données datetime2 en un type de données datetime a entraîné une valeur hors limites.
Mes objets d'entité sont tous alignés sur les objets de base de données.
Je n'ai trouvé qu'une seule référence à cette erreur via Google:
Après avoir lu ceci, je me souviens que nous avons ajouté 2 champs, puis mis à jour le modèle d'entité à partir de VS 2010. Je ne suis pas sûr de ce qu'il entend par "coder à la main" les différences. Je n'en vois pas.
Tout ce que je fais dans le code est de renseigner l'objet entité puis de l'enregistrer. (Je renseigne également les nouveaux champs dans le code) J'ai renseigné le champ de date avec DateTime.Now
..
La partie importante du code est la suivante: ctx.SaveChanges(SaveOptions.AcceptAllChangesAfterSave);
La base de données est SQL Server 2008.
Pensées?
Le reste de l'erreur:
sur System.Data.Mapping.Update.Internal.UpdateTranslator.Update (IEntityStateManager stateManager, adaptateur IEntityAdapter) à System.Data.EntityClient.EntityAdapter.Update (IEntityStateManager entityCache) sur System.Data.Objects.ObjectContext.SaveChanges (options SaveOptions) à l'adresse SafariAdmin.Site.WebServices.SpeciesPost.SaveOrUpdateSpecies (String sid, String fieldName, String authToken) dans SpeciesPost.svc.cs: ligne 58 sur SafariAdmin.TestHarness.Tests.Site.WebServices.SpeciesPostSVC_Tester.SaveNewSpecies () dans SpeciesPostSVC_Tester.cs: ligne 33 --SqlException at System.Data.SqlClient.SqlConnection.OnError (exception SqlException, Boolean breakConnection) à l'adresse System.Data.SqlClient.SqlInternalConnection.OnError (exception SqlException, Boolean breakConnection) à System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning () à System.Data.SqlClient.TdsParser.Run (RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj. sur System.Data.SqlClient.SqlDataReader.ConsumeMetaData () sur System.Data.SqlClient.SqlDataReader.get_MetaData () sur System.Data.SqlClient.SqlCommand.FinishExecuteReader (SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) sur System.Data.SqlClient.SqlCommand.RunExecuteReaderTds (CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) at System.Data.SqlClient.SqlCommand.RunExecuteReader (CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Méthode String, résultat DbAsyncResult) sur System.Data.SqlClient.SqlCommand.RunExecuteReader (CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, méthode String) sur System.Data.SqlClient.SqlCommand.ExecuteReader (comportement CommandBehavior, méthode String) sur System.Data.SqlClient.SqlCommand.ExecuteDbDataReader (comportement CommandBehavior) dans System.Data.Common.DbCommand.ExecuteReader (comportement CommandBehavior) at System.Data.Mapping.Update.Internal.DynamicUpdateCommand.Execute (traducteur UpdateTranslator, connexion EntityConnection, Dictionary
2 identifierValues, List
1 createdValues). sur System.Data.Mapping.Update.Internal.UpdateTranslator.Update (IEntityStateManager stateManager, adaptateur IEntityAdapter)
Entity Framework gère toutes les dates sous la forme d'une date/heure2, ainsi, si vos champs de la base de données sont datetime, cela pourrait être un problème . Nous avons eu le même problème ici, et d'après ce que nous avons trouvé, remplir tous les champs de date et changer le type de données, sont les solutions les plus courantes
Si vous utilisez Code First, vous devez déclarer une propriété DateTime
facultative en tant que DateTime?
ou Nullable<DateTime>
. Les objets non définis DateTime
peuvent être à l'origine de problèmes.
Si la propriété a la valeur nullable dans la base de données et une DateTime
standard dans le code (et non le DateTime?
), ADO.NET enverra une commande d'insertion avec la date 0001-01-01 (et non la NULL
), mais la valeur SQL DateTime minimale est 1753- 01-01, provoquant une erreur. Si votre propriété DateTime
dans le code est nullable (par exemple, DateTime?
ou Nullable<DateTime>
), la commande insert essaiera d'insérer une NULL
à la place d'une date hors limites.
Utilisez ce script SQL pour convertir toutes les colonnes de datetime en datetime2
. Il saute toutes les tables contenant «aspnet» pour votre commodité.
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;
Ça marche pour moi!
Une autre solution possible consiste à définir le type de colonne SQL du champ sur datetime2. cela peut être fait en utilisant fluentapi.
Property(x => x.TheDateTimeField)
.HasColumnType("datetime2");
Remarque: Il s’agit d’une solution à partir de 2008 pour SQL Server 2008, car datetime2 n’est pas disponible pour SQL Server 2005 ou une version antérieure.
J'ai eu le même problème et le résoudre en mettant l'attribut [Column(TypeName = "datetime2")]
aux propriétés associées, comme ci-dessous exemple:
[Column(TypeName = "datetime2")]
public DateTime? PropertyName { get; set; }
Je sais que c’est une vieille question, mais comme je cherchais dans Google, quelqu'un d’autre pourrait faire de même; -) Pour ceux qui ne passent pas de DateTime à DateTime2, je pense que Dans la plupart des cas, il est plus raisonnable de renseigner des champs laissés vides avec quelque chose comme (DateTime)System.Data.SqlTypes.SqlDateTime.MinValue
et pas avec DateTime.now, car il est plus facile de la reconnaître en tant que valeur "pseudo-nulle" (et le cas échéant, convertissez-la en valeur NULL dans une classe d'objet père partielle)
Lorsque vous utilisez d’abord le code cadre d’entité, déclarez-le comme ceci:
public Nullable<System.DateTime> LastLogin { get; set; }
On avait le même problème. Cela était lié à la version mssql ..__ Nous avons fait en sorte que cela fonctionne sur toute notre version avec cette méthode.
Ouvrez votre fichier edmx avec un éditeur xml .__ Trouvez cette ligne en haut de votre fichier
<Schema Namespace="XXXXX.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2008"
Remplacez 2008 par 2005 Enregistrez votre fichier, recompilez le projet.
J'espère que cela aidera quelqu'un d'autre dans le futur.
J'ai seulement essayé cette solution avec une approche dbfirst.
Existe-t-il une propriété ModifiedTime dans votre entité, qui est mise à jour uniquement du côté base de données? Dans ce cas, vous devez utiliser DatabaseGeneratedOption.Computed (pour EF CodeFirst). Visitez également cette https://stackoverflow.com/a/9508312/1317263
Je vous remercie.
Quel que soit le type de date/heure, le type de données datetime2 et inversement, ce n'est pas le cas, vous pouvez coller une date de janvier 1500 dans un type de données datetime2, mais datetime ne remonte qu'à 1753, une colonne datetime2 peut renvoyer tous les chemin vers l'année 1. Je voudrais vérifier quelle est la date minimale que vous transmettez et si vos tables ont des colonnes de type de données datetime2 ou datetime
Assurez-vous qu'aucun des champs non NULL de la base de données (date/heure) ne soit omis lors de l'insertion/de la mise à jour. J'ai eu la même erreur et lors de l'insertion de valeurs dans ces champs de date/heure, le problème a été résolu. Cela se produit si une valeur correcte n'est pas attribuée aux champs de date/heure non null.
Après avoir tenté de résoudre ce problème pendant plusieurs jours, j'ai utilisé DateTime?
comme type de données dans mon modèle avec Entity Framework Code-First au lieu de DateTime
.
J'ai eu le même problème dans mon application ASP.Net MVC.
Dans mon application, deux classes de modèle avaient des propriétés DateTime.
lors de l’examen, j’ai remarqué que la propriété DateTime d’un modèle était nullable, c’est-à-dire pour la rendre facultative, date de naissance
l'autre modèle avait une propriété DateTime avec l'annotation de données requise (une erreur se produit lors de l'enregistrement de ce modèle)
mon application est d'abord le code, j'ai donc résolu le problème en définissant le type de données sur DateTime2
[Column(TypeName="datetime2")]
j'ai ensuite exécuté la migration sur la console du gestionnaire de paquets.
Simple . Sur votre code en premier, définissez le type de DateTime sur DateTime? . Ainsi, vous pouvez utiliser un type DateTime nullable dans la base de données.
Cela fait suite à la réponse de stepanZ ... J'ai eu cette erreur en utilisant Entity Framework Code First
avec AutoMapper
.
Lors de la configuration de la variable AutoMapping
, nous avons les champs createddt
, updateddt
, createdby
et updatedby
qui sont définis automatiquement dans notre fonction public override int SaveChanges()
. Pour ce faire, vous devez vous assurer que ces champs sont ignorés par AutoMapper
, sinon la base de données sera mise à jour avec null
pour ces champs quand ils ne sont pas fournis à partir de View
.
Mon problème était que j'avais mis la source et la destination dans le mauvais sens, donc en essayant d'ignorer les champs lors de la définition de ViewModel
, au lieu de lors de la définition de Model
.
La Mapping
ressemblait à ceci lorsque j'ai reçu cette erreur (remarque: la cfg.CreateMap<Source, Destination>()
de la deuxième ligne mappe la Model
sur la ViewModel
et la définition de la 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());
La source et la destination doivent être ignorées pour un mappage de ViewModel
à Model
(remarque: le code ci-dessous est correct lorsque Ignore()
est placé par rapport au mappage de ViewModel
à 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());