577 votes

Impossible de mettre à jour l'EntitySet - car il a une DefiningQuery et aucun élément <UpdateFunction> n'existe

Je suis en train d'utiliser Entity Framework 1 avec .net 3.5.

Je fais quelque chose de simple comme ceci :

var roomDetails = context.Rooms.ToList();

foreach (var room in roomDetails)
{        
   room.LastUpdated = DateTime.Now;
}

Je reçois cette erreur lorsque j'essaie de faire :

 context.SaveChanges();

Je reçois l'erreur :

Impossible de mettre à jour l'EntitySet - car il a une DefiningQuery et aucun élément n'existe dans l'élément pour prendre en charge l'opération actuelle.

Je fais beaucoup de mises à jour sur le contexte et je n'ai aucun problème, c'est seulement lorsque j'essaie de mettre à jour cette entité en particulier.

Toutes mes recherches montrent la même chose, qu'il n'y a pas de clé primaire déclarée sur l'entité que j'essaie de mettre à jour. Mais hélas, j'ai bien une clé primaire déclarée...

67 votes

J'ai fait une erreur, il n'y avait pas de clé primaire définie sur la table, merci pour votre temps! Désolé pour le désagrément!

2 votes

Il vient de m'arriver - j'ai probablement créé 1000 tables avec des clés primaires et en ai oublié une - le message d'exception n'est pas très utile

1 votes

Excellent. vraiment j'ai oublié d'ajouter la clé primaire à la Table. Essayons d'être prudent)

1090voto

Ladislav Mrnka Points 218632

Cela se produit généralement pour l'une des raisons suivantes :

  • L'Entity Set est mappé à partir de la vue de base de données
  • Une requête personnalisée à la base de données
  • La table de base de données n'a pas de clé primaire

Après avoir effectué ces étapes, vous devrez peut-être toujours mettre à jour le concepteur Entity Framework (ou supprimer l'entité puis l'ajouter de nouveau) avant de cesser de recevoir l'erreur.

2 votes

Assurez-vous également de changer store:Schema en simplement Schema pour cet EntitySet si vous rencontrez toujours des problèmes.

0 votes

Donc, la solution est d'ajouter une clé primaire alors?

55 votes

Ensuite, supprimez et recréez l'entité car la mise à jour ne fonctionne pas correctement dans le concepteur EF.

100voto

Jebastin J Points 191

Ajoutez simplement une clé primaire à la table. C'est tout. Problème résolu.

ALTER TABLE 
AJOUTER CONTRAINTE  CLÉ PRIMAIRE()

19 votes

Et n'oubliez pas de cliquer sur "Mettre à jour le modèle à partir de la base de données" sur votre fichier .edmx

0 votes

@BasharAbuShamaa cette réponse n'est pas valable sans ce détail.

45voto

majidgeek Points 2781

Notez simplement que peut-être votre Entité possède une clé primaire mais que votre table dans la base de données n'en possède pas.

2 votes

Comment surmonter, si nous ne pouvons pas changer la table de la base de données?

0 votes

Si vous pouvez changer la table de la base de données pour avoir une clé primaire, alors le générateur de code cessera de commettre les mêmes erreurs. Supprimer la clé de EF causera de nombreux autres problèmes.

34voto

Pharylon Points 419

MISE À JOUR : J'ai reçu quelques votes positifs récemment, donc je me suis dit que je devrais informer les gens que le conseil que je donne ci-dessous n'est pas le meilleur. Depuis que j'ai commencé à bricoler avec Entity Framework sur d'anciennes bases de données sans clé, j'ai réalisé que la meilleure chose à faire, DE LOIN, est de le faire en reverse code-first. Il y a quelques bons articles sur la façon de le faire. Il suffit de les suivre, puis quand vous voulez ajouter une clé, utilisez des annotations de données pour "faire semblant" de la clé.

Par exemple, disons que je sais que ma table Commandes, bien qu'elle n'ait pas de clé primaire, est assurée d'avoir uniquement un numéro de commande par client. Comme ce sont les deux premières colonnes de la table, je configurerais les classes de code en premier de cette façon:

    [Key, Column(Order = 0)]
    public Int32? NumeroCommande { get; set; }

    [Key, Column(Order = 1)]
    public String Client { get; set; }

En faisant cela, vous faites en quelque sorte croire à EF qu'il y a une clé cluster composée de NumeroCommande et Client. Cela vous permettra d'insérer, de mettre à jour, etc. sur votre table sans clé.

Si vous n'êtes pas trop familier avec la réalisation du reverse Code First, trouvez un bon tutoriel sur Entity Framework Code First. Ensuite, trouvez-en un sur le Reverse Code First (qui consiste à faire du Code First avec une base de données existante). Ensuite, revenez ici et regardez à nouveau mes conseils sur les clés. :)

Réponse Originale:

Premièrement: comme d'autres l'ont dit, la meilleure option est d'ajouter une clé primaire à la table. Point final. Si vous pouvez le faire, ne lisez pas la suite.

Mais si vous ne pouvez pas, ou si vous vous détestez simplement, il y a un moyen de le faire sans la clé primaire.

Dans mon cas, je travaillais avec un système hérité (à l'origine des fichiers plats sur un AS400 portés vers Access, puis portés vers T-SQL). J'ai donc dû trouver une solution. Voici ma solution. Ce qui suit a fonctionné pour moi en utilisant Entity Framework 6.0 (la dernière version sur NuGet à l'heure actuelle).

  1. Cliquez avec le bouton droit sur votre fichier .edmx dans l'Explorateur de solutions. Choisissez "Ouvrir avec..." puis sélectionnez "Éditeur XML (Texte)". Nous allons modifier manuellement le code généré ici.

  2. Recherchez une ligne comme celle-ci:

  3. Supprimez store:Nom="nom_table" à la fin.

  4. Changez store:Schéma="quelquechose" en Schéma="quelquechose"

  5. Recherchez en dessous de cette ligne et trouvez la balise . Elle contiendra une grande instruction select. Supprimez la balise et son contenu.

  6. Maintenant votre ligne devrait ressembler à cela:

  7. Nous avons quelque chose d'autre à changer. Parcourez votre fichier et trouvez ceci:

  8. À proximité, vous verrez probablement un texte commenté vous avertissant qu'aucune clé primaire n'a été identifiée, donc la clé a été déduite et la définition est une table/vue en lecture seule. Vous pouvez le laisser ou le supprimer. Je l'ai supprimé.

  9. En dessous se trouve la balise . C'est ce qu'Entity Framework va utiliser pour effectuer des insertions/mises à jour/suppressions. ALORS ASSUREZ-VOUS DE LE FAIRE CORRECTEMENT. La propriété (ou les propriétés) dans cette balise doivent indiquer une ligne identifiable de manière unique. Par exemple, disons que je sais que ma table commandes, bien qu'elle n'ait pas de clé primaire, est assurée d'avoir uniquement un numéro de commande par client.

Donc, le mien ressemble à ceci:

Sérieusement, ne faites pas d'erreur. Disons qu' même s'il ne devrait jamais y avoir de doublons, deux rangées se retrouvent d'une manière quelconque dans mon système avec le même numéro de commande et le même nom de client. Oups ! C'est ce que j'obtiens en n'utilisant pas de clé ! Alors j'utilise Entity Framework pour en supprimer un. Parce que je sais que le doublon est la seule commande entrée aujourd'hui, je fais ceci:

var commandeDoublon = myModel.commandes.First(x => x.date_commande == DateTime.Today);
myModel.commandes.Remove(commandeDoublon);

Devinez quoi ? J'ai juste supprimé à la fois le doublon ET l'original ! C'est parce que j'ai dit à Entity Framework que numero_commande/nom_client était ma clé primaire. Donc quand je lui ai dit de supprimer commandeDoublon, ce qu'il a fait en arrière-plan était quelque chose comme:

DELETE FROM commandes
WHERE numero_commande = (numéro de commande du doublon)
ET nom_client = (nom du client du doublon)

Et avec cet avertissement... vous devriez maintenant être prêt à partir !

0 votes

Trouvé cette réponse après avoir trouvé la même solution au problème. Certainement la réponse correcte! Se contenter de définir une clé primaire comme mentionné dans d'autres réponses ne suffira pas dans de nombreux cas.

20voto

mob1lejunkie Points 474

Cela peut également se produire si le modèle de données est obsolète.

J'espère que cela évitera la frustration à quelqu'un d'autre :)

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