web-dev-qa-db-fra.com

Erreur 'datetime2' lors de l'utilisation d'une structure d'entité dans VS 2010 .net 4.0

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:

Résultat 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, Dictionary2 identifierValues, List1 createdValues). sur System.Data.Mapping.Update.Internal.UpdateTranslator.Update (IEntityStateManager stateManager, adaptateur IEntityAdapter) 

60
KevinDeus

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

64
Tejo

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.

49
stepanZ

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!

13
Roman Pushkin

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.

8
InsI

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; }
7

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)

5
ale.com

Lorsque vous utilisez d’abord le code cadre d’entité, déclarez-le comme ceci:

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

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.

2
pix

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.

2
eLVik

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

1
SQLMenace

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.

1
vidya

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.

1
jaminyah

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.

1
Taha

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.

0
Ulisses Ottoni

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());
0
Gwasshoppa