J'utilise les API DbContext et Code First introduites avec Entity Framework 4.1.
Le modèle de données utilise des types de données de base tels que string
et DateTime
. La seule annotation de données que j'utilise dans certains cas est [Required]
, mais ce n'est sur aucune des DateTime
propriétés. Exemple:
public virtual DateTime Start { get; set; }
La sous - classe DbContext est également simple et ressemble à:
public class EventsContext : DbContext
{
public DbSet<Event> Events { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Event>().ToTable("Events");
}
}
L' initialiseur définit les dates du modèle sur des valeurs raisonnables pour cette année ou l'année prochaine.
Cependant, lorsque j'exécute l'initialiseur, j'obtiens cette erreur à context.SaveChanges()
:
La conversion d'un type de données datetime2 en un type de données datetime a abouti à une valeur hors plage. La déclaration a été terminée.
Je ne comprends pas du tout pourquoi cela se produit parce que tout est si simple. Je ne sais pas non plus comment le réparer car il n'y a pas de fichier edmx à modifier.
Des idées?
la source
Réponses:
Vous devez vous assurer que Start est supérieur ou égal à SqlDateTime.MinValue (1er janvier 1753) - par défaut, Start est égal à DateTime.MinValue (1er janvier 0001).
la source
Facile. Sur votre code d'abord, définissez le type de DateTime sur DateTime?. Vous pouvez donc travailler avec le type DateTime nullable dans la base de données. Exemple d'entité:
la source
Dans certains cas,
DateTime.MinValue
(ou de manière équivalentedefault(DateTime)
) est utilisé pour indiquer une valeur inconnue.Cette méthode d'extension simple peut aider à gérer de telles situations:
Usage:
la source
Vous pouvez rendre le champ nullable, si cela répond à vos préoccupations de modélisation spécifiques. Une date nulle ne sera pas forcée à une date qui n'est pas dans la plage du type SQL DateTime comme le ferait une valeur par défaut. Une autre option consiste à mapper explicitement à un type différent, peut-être avec,
la source
Même si cette question est assez ancienne et qu'il y a déjà d'excellentes réponses, j'ai pensé que je devrais en poser une de plus qui explique 3 approches différentes pour résoudre ce problème.
1ère approche
Carte Explicitement
DateTime
propriétépublic virtual DateTime Start { get; set; }
àdatetime2
la colonne correspondante du tableau. Parce que par défaut, EF le mappera àdatetime
.Cela peut être fait par une API fluide ou une annotation de données.
API Fluent
Dans la classe DbContext
OnModelCreating
, remplacez et configurez la propriétéStart
(pour des raisons d'explication, c'est une propriété de la classe EntityClass).Annotation des données
2ème approche
Initialisez
Start
à une valeur par défaut dans le constructeur EntityClass. C'est bien comme si, pour une raison quelconque, la valeur deStart
n'est pas définie avant l'enregistrement de l'entité dans le démarrage de la base de données aura toujours une valeur par défaut. Assurez-vous que la valeur par défaut est supérieure ou égale à SqlDateTime.MinValue (du 1er janvier 1753 au 31 décembre 9999)3e approche
Faire
Start
en sorte qu'il soit de typeDateTime
nullable -note?
aprèsDateTime
-Pour plus d'explications, lisez cet article
la source
Si vos
DateTime
propriétés peuvent être nulles dans la base de données, assurez-vous de les utiliserDateTime?
pour les propriétés d'objet associées, sinon EF passeraDateTime.MinValue
pour les valeurs non attribuées qui sont en dehors de la plage de ce que le type de date / heure SQL peut gérer.la source
Ma solution était de basculer toutes les colonnes datetime en datetime2 et d'utiliser datetime2 pour toutes les nouvelles colonnes. En d'autres termes, faites en sorte qu'EF utilise datetime2 par défaut. Ajoutez ceci à la méthode OnModelCreating sur votre contexte:
Cela obtiendra tous les DateTime et DateTime? properties sur toutes vos entités.
la source
initialiser la propriété Start dans le constructeur
Cela a fonctionné pour moi lorsque j'essayais d'ajouter quelques nouveaux champs à la table des utilisateurs de ASP .Net Identity Framework (AspNetUsers) en utilisant Code First. J'ai mis à jour la classe - ApplicationUser dans IdentityModels.cs et j'ai ajouté un champ lastLogin de type DateTime.
la source
En fonction de la réponse de user @ andygjp, il est préférable de remplacer la
Db.SaveChanges()
méthode de base et d'ajouter une fonction pour remplacer toute date qui ne tombe pas entre SqlDateTime.MinValue et SqlDateTime.MaxValue.Voici l exemple de code
Tiré du commentaire de l'utilisateur @ sky-dev sur https://stackoverflow.com/a/11297294/9158120
la source
J'ai eu le même problème et dans mon cas, je définissais la date sur le nouveau DateTime () au lieu de DateTime.
la source
Dans mon cas, cela s'est produit lorsque j'ai utilisé entity et que la table sql a la valeur par défaut datetime == getdate (). alors ce que j'ai fait pour définir une valeur dans ce champ.
la source
J'utilise Database First et lorsque cette erreur m'est arrivée, ma solution était de forcer ProviderManifestToken = "2005" dans le fichier edmx (rendant les modèles compatibles avec SQL Server 2005). Je ne sais pas si quelque chose de similaire est possible pour Code First.
la source
Une ligne corrige ceci:
Donc, dans mon code, j'ai ajouté:
L'ajout d'une ligne à la section de remplacement de sous-classe DBContext void OnModelCreating devrait fonctionner.
la source
Dans mon cas, après quelques refactorisations dans EF6, mes tests échouaient avec le même message d'erreur que l'affiche d'origine mais ma solution n'avait rien à voir avec les champs DateTime.
Il me manquait juste un champ obligatoire lors de la création de l'entité. Une fois que j'ai ajouté le champ manquant, l'erreur a disparu. Mon entité a deux DateTime? champs mais ce n'était pas le problème.
la source