198 votes

La conversion d'un type de données datetime2 en un type de données datetime a donné lieu à une valeur hors plage.

J'ai le code suivant dans mon HomeController :

public ActionResult Edit(int id)
{
    var ArticleToEdit = (from m in _db.ArticleSet where m.storyId == id select m).First();
    return View(ArticleToEdit);
}

[ValidateInput(false)]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Article ArticleToEdit)
{
    var originalArticle = (from m in _db.ArticleSet where m.storyId == ArticleToEdit.storyId select m).First();
    if (!ModelState.IsValid)
        return View(originalArticle);

    _db.ApplyPropertyChanges(originalArticle.EntityKey.EntitySetName, ArticleToEdit);
    _db.SaveChanges();
    return RedirectToAction("Index");
}

Et voici la vue de la méthode d'édition :

<% using (Html.BeginForm()) {%>

    <fieldset>
        <legend>Fields</legend>
        <p>
            <label for="headline">Headline</label>
            <%= Html.TextBox("headline") %>
        </p>
        <p>
            <label for="story">Story <span>( HTML Allowed )</span></label>
            <%= Html.TextArea("story") %>
        </p>
        <p>
            <label for="image">Image URL</label>
            <%= Html.TextBox("image") %>
        </p>
        <p>
            <input type="submit" value="Post" />
        </p>
    </fieldset>

<% } %>

Lorsque j'appuie sur le bouton "soumettre", j'obtiens l'erreur suivante : {"The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value.\r\nThe statement has been terminated."} Une idée du problème ? Je suppose que la méthode d'édition essaie de mettre à jour la valeur affichée dans la base de données avec la valeur éditée, mais pour une raison quelconque, elle n'aime pas ça... Je ne vois pas pourquoi la date est impliquée car elle n'est pas mentionnée dans la méthode du contrôleur pour l'édition ?

1 votes

modelBuilder.Entity<WorldInfo>().Property(d => d.CurrentTime).HasColumnType("datetime2");

181voto

Jacob Points 33729

Le problème est que vous utilisez ApplyPropertyChanges avec un objet modèle qui n'a été alimenté que par les données du formulaire (titre, article et image). ApplyPropertyChanges applique les changements à toutes les propriétés de l'objet, y compris celles qui ne sont pas initialisées. DateTime qui a pour valeur 0001-01-01, ce qui est en dehors de la plage de valeurs du serveur SQL. DATETIME .

Plutôt que d'utiliser ApplyPropertyChanges Si vous avez besoin de modifier votre formulaire, je vous suggère de récupérer l'objet en cours de modification, de modifier les champs spécifiques que votre formulaire édite, puis d'enregistrer l'objet avec ces modifications ; de cette façon, seuls les champs modifiés le sont. Vous pouvez également placer des entrées cachées dans votre page avec les autres champs remplis, mais cela ne serait pas très convivial pour les modifications simultanées.

Mise à jour :

Voici un exemple non testé de mise à jour de certains champs de votre objet (en supposant que vous utilisez LINQ to SQL) :

var story = _db.ArticleSet.First(a => a.storyId == ArticleToEdit.storyId);
story.headline = ArticleToEdit.headline;
story.story = ArticleToEdit.story;
story.image = ArticleToEdit.image;
story.modifiedDate = DateTime.Now;
_db.SubmitChanges();

0 votes

Très utile :) Je me demandais pourquoi la date était modifiée alors que je ne l'avais pas spécifiée. Pouvez-vous m'aider à modifier la méthode d'édition pour qu'elle n'utilise plus la fonction ApplyPropertyChanges ? Je suis nouveau en ASP.NET et je ne comprends pas tout pour le moment. Merci mon ami.

0 votes

Et si je voulais définir la date à la date actuelle, c'est-à-dire la date à laquelle l'article a été mis à jour ? C'est probablement la meilleure option et je suppose qu'elle fonctionnerait avec la fonction ApplyPropertyChanges que j'ai mise en place.

0 votes

Voir mon édition (elle suppose que modifiedDate est le nom de votre propriété)

130voto

Il s'agit d'une erreur courante à laquelle les gens sont confrontés lorsqu'ils utilisent Entity Framework. Elle se produit lorsque l'entité associée à la table en cours d'enregistrement possède un champ date obligatoire et que vous ne lui attribuez pas de valeur.

L'objet datetime par défaut est créé avec une valeur de 01/01/1000 et sera utilisé à la place de null. Il sera envoyé à la colonne datetime qui peut contenir des valeurs de date de 1753-01-01 00:00:00 à partir de, mais pas avant, ce qui conduit à l'exception hors gamme.

Cette erreur peut être résolue soit en modifiant le champ de la base de données pour qu'il accepte null, soit en initialisant le champ avec une valeur.

6 votes

Cela se produit lorsque le champ date dans la base de données est facultatif et que la valeur n'est pas définie. Il ne s'agit donc pas d'une erreur courante, mais d'un problème d'architecture de EF.

1 votes

Je suis d'accord que EF devrait voir le type en DB et s'adapter en conséquence ou lancer ou au moins lancer une erreur plus précise. D'un autre côté, j'aime votre réponse puisque vous avez fourni 2 options au lieu de l'habituelle - initialiser le fichier avec la valeur minimale.

0 votes

Cela a résolu mon problème. En particulier, j'essayais de transmettre uniquement l'année et non une date valide (ex : 01-05-2021).

47voto

Andrew Orsich Points 24503

DATETIME supporte 1753/1/1 à "éternité" (9999/12/31), tandis que DATETIME2 soutien du 0001/1/1 au l'éternité.

Msdn

Réponse : Je suppose que vous essayez de sauver DateTime avec la valeur "0001/1/1". Il suffit de mettre un point d'arrêt et de déboguer, si c'est le cas, il faut remplacer DateTime con null ou fixer une date normale.

0 votes

Mais qu'est-ce que je mets dans le contrôleur ? Le débogage ne fait que faire apparaître l'erreur que j'ai postée ci-dessus. Merci.

0 votes

Il semble y avoir une erreur ici -> _db.SaveChanges() ; Vous pouvez définir un point d'arrêt avant cette ligne...

0 votes

Oui, c'est vrai. Ensuite, il est indiqué qu'une erreur s'est produite lors de la sauvegarde des modifications. Je regarde l'InnerException et il est indiqué que c'est à cause de l'erreur affichée, donc c'est l'erreur !

17voto

sky-dev Points 1990

Celui-là me rendait fou. Je voulais éviter l'utilisation d'une date et d'une heure invalides ( DateTime? ). Je n'avais pas non plus la possibilité d'utiliser le type datetime2 de SQL 2008 ( modelBuilder.Entity<MyEntity>().Property(e => e.MyDateColumn).HasColumnType("datetime2"); ).

J'ai finalement opté pour ce qui suit :

public class MyDb : DbContext
{
    public override int SaveChanges()
    {
        UpdateDates();
        return base.SaveChanges();
    }

    private void UpdateDates()
    {
        foreach (var change in ChangeTracker.Entries<MyEntityBaseClass>())
        {
            var values = change.CurrentValues;
            foreach (var name in values.PropertyNames)
            {
                var value = values[name];
                if (value is DateTime)
                {
                    var date = (DateTime)value;
                    if (date < SqlDateTime.MinValue.Value)
                    {
                        values[name] = SqlDateTime.MinValue.Value;
                    }
                    else if (date > SqlDateTime.MaxValue.Value)
                    {
                        values[name] = SqlDateTime.MaxValue.Value;
                    }
                }
            }
        }
    }
}

8voto

Patrick Points 51

Si vous avez une colonne de type date et que vous autorisez les nullités, vous obtiendrez cette erreur. Je vous recommande de définir une valeur à transmettre à l'objet avant d'utiliser la fonction .SaveChanges() ;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X