Étrange entité de mise à jour dans l'Entity Framework Code First
Je suis de résoudre le problème avec la mise à jour de l'entité avant l'enregistrement dans la base de données et eu un comportement étrange.
Je suis en utilisant Entity Framework 4.1 Code-Première dans ASP.NET MVC 3 l'application web. Voici le modèle:
public class Order
{
public int OrderId { get; set; }
public int CarId { get; set; }
public DateTime BeginRentDate { get; set; }
public DateTime EndRentDate { get; set; }
public decimal RentPrice { get; set; }
public virtual Car Car { get; set; }
}
public class Car
{
public int CarId { get; set; }
public string Brand { get; set; }
public string Model { get; set; }
public string NumberPlate { get; set; }
public decimal RentPrice { get; set; }
}
Chaque Voiture a une RentPrice. Ce prix doit être copié à l'Ordre du RentPrice lors de la création d'un. La voiture est la sélection par l'utilisateur de telle sorte initialement de l'Ordre.RentPrice est de 0.
Ici je veux copier la valeur des prix:
[HttpPost]
public ActionResult Create(Order order)
{
order.RentPrice = _context.Cars.Find(order.CarId).RentPrice;
if (ModelState.IsValid)
{
_context.Orders.Add(order);
_context.SaveChanges();
return RedirectToAction("Index");
}
return View(order);
}
Il ne fonctionne pas en raison d'une erreur sur le SaveChanges
que l'entité a des erreurs de validation. OK. J'ai trouvé que devez d'abord appeler UpdateModel(order);
et ensuite modifier les valeurs.
Donc ce que j'ai. Code de travail:
_context.Orders.Add(order);
UpdateModel(order);
order.RentPrice = 777;
_context.SaveChanges();
Pas code de travail:
_context.Orders.Add(order);
UpdateModel(order);
order.RentPrice = _context.Cars.Find(order.CarId).RentPrice;
_context.SaveChanges();
Code de travail (!):
_context.Orders.Add(order);
UpdateModel(order);
var t = (double)_context.Cars.Find(order.CarId).RentPrice;
order.RentPrice = (decimal)t;
_context.SaveChanges();
Quelqu'un peut m'expliquer, s'il vous plaît, de ce qui se passe ici? Surtout magie sur les 3e et 4e lignes dans le dernier bloc de code.
Mise à jour
Je suis DbEntityValidationException
: "la Validation a échoué à une ou plusieurs entités. Voir " EntityValidationErrors la propriété pour plus de détails."
De l'intérieur de l'exception: "OriginalValues ne peut pas être utilisé pour les entités mentionnées à l'Ajout de l'état."
- Avez-vous remarqué que vous aviez deux points-virgules à la fin de la commande.RentPrice = _context.Des voitures.Trouver(de l'ordre.CarId).RentPrice;; --> dans la prochaine pour le dernier bloc de code?
- quelles sont les erreurs de validation sur la méthode SaveChanges? Le code dans votre création initiale de la méthode fonctionne très bien pour moi.
- juste une fautes de frappe lors de l'écriture de post. Fixe.
- J'ai ajouté exception que je suis dans l'ensemble pas de travail exemples de code.
- Le premier extrait de code avec votre post d'action de donner la même erreur de validation "OriginalValues ne peut pas être utilisé pour les entités mentionnées à l'Ajout de l'état"? Je ne crois pas... Si non, qu'est-ce que la validation d'erreur dans ce code? Je crois que c'est ici le conseil important.
- oui. Exactement la même exception.
Vous devez vous connecter pour publier un commentaire.
Lorsque vous obtenez
Cela signifie qu'il y a des erreurs comme not NULL colonnes qui étaient vides ou d'autres contraintes , vérifiez l'entité erreurs de validation par le débogage ou comme
Peut être corrigé en veillant à ce que non identité champs de clé primaire sont spécifiés comme pas généré dans le modèle.
L'erreur est en fait auto-explicatif lorsque vous avez contexte, mais inexplicable autrement. La base de données génère deux états pour l'insertion, la seconde est:
Cette déclaration ne sera pas renvoyer toutes les lignes pour non identité colonnes. D'où la
OriginalValues
restera inchangée dans l'ajout de l'état. Cela explique aussi pourquoi cette exception est enveloppé dans unOptimisticConcurrencyException
que le nombre de lignes affectées est utilisé pour détecter existant de données altérées.Avez-vous déclaré la clé primaire n'importe où? Vous devriez le faire soit à l'aide de FluentAPI ou de l'attribut comme ceci:
Ou dans votre Contexte, vous pouvez utiliser l'API Fluent pour déclarer la clé, comme ce
J'ai une idée, mais c'est plus une supposition... Peut-être que le temps que vous obtenez dans cette de Créer la fonction, le contexte sait déjà de cet Ordre? Si elle le fait, d'essayer de l'ajouter de nouveau de nouveau pourrait peut-être vous donner l'erreur.
Dans votre dernier morceau de code (celui qui étonnamment travail), avez-vous essayé d'utiliser un intermédiaire var sans la conversion en double?
Je suis également intrigué de cette UpdateModel... je utiliser EF mais pas de MVC, donc peut-être qu'il n'a rien à faire à ce sujet, mais si c'est une fonction personnalisée, que fait-il?
Je suis sûr que le problème aurait été résolu il y a longtemps, je voulais juste apporter ma contribution de 2 cents.
J'ai aussi rencontré un problème avec le même message d'erreur, j'ai été en utilisant Oracle et EF 5.0. J'ai finalement trouvé une solution après avoir englouti plus de 12 heures.
Pour moi, c'était l'absence des autorisations de l'utilisateur sur la table où j'ai essayé d'insérer des valeurs et le message d'erreur absolument a pas de conseils de réel problème de permission, ce qui était vraiment bizarre.
Espère que quelqu'un le trouve utile et de ne pas perdre des heures comme moi dans le dépannage.
Acclamations,
Avi