'/> '/> '/> Impossible de mettre à jour l'EntitySet, car il possède un élément DefiningQuery et aucun élément <UpdateFunction> | abulletproofidea.com

Question Impossible de mettre à jour l'EntitySet, car il possède un élément DefiningQuery et aucun élément


J'utilise Entity Framework 1 avec .net 3.5.

Je fais quelque chose de simple comme ceci:

var RoomDetails = context.Rooms.ToList();

foreach (var Room in Rooms)
{        
   Room.LastUpdated = DateTime.Now;
}

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

 context.SaveChanges();

J'ai l'erreur:

Impossible de mettre à jour EntitySet - car il possède DefiningQuery et aucun élément <UpdateFunction> n'existe dans l'élément <ModificationFunctionMapping> pour prendre en charge l'opération en cours.

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

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


448
2017-09-28 13:09


origine


Réponses:


Cela arrive généralement parce que l'une des raisons suivantes:

  • Le jeu d'entités est mappé à partir de la vue Base de données
  • Une requête de base de données personnalisée
  • La table de base de données n'a pas de clé primaire

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


864
2017-09-28 13:11



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

ALTER TABLE <TABLE_NAME>
ADD CONSTRAINT <CONSTRAINT_NAME> PRIMARY KEY(<COLUMN_NAME>)

78
2018-03-28 09:20



C'est le cas pour moi. La simple suppression a entraîné une autre erreur. J'ai suivi les étapes de ce post sauf le dernier. Pour votre commodité, j'ai copié les 4 étapes du post que j'ai suivi pour résoudre le problème comme suit:

  1. Faites un clic droit sur le fichier edmx, sélectionnez Ouvrir avec, éditeur XML
  2. Localisez l'entité dans l'élément edmx: StorageModels
  3. Supprimer le DefiningQuery entièrement
  4. Renommez le store:Schema="dbo" à Schema="dbo" (sinon, le code générera une erreur indiquant que le nom est invalide)

47
2018-01-21 07:20



Notez que peut-être votre Entité avoir clé primaire mais votre table dans la base de données n'a pas clé primaire.


37
2017-09-13 07:57



METTRE À JOUR: J'ai reçu quelques commentaires à ce sujet ces derniers temps, alors j'ai pensé que je ferais savoir aux gens que les conseils que je donne ci-dessous ne sont pas les meilleurs. Comme je commençais à utiliser Entity Framework sur les anciennes bases de données sans clé, je me suis rendu compte que la meilleure chose à faire est de le faire en inversant le code. Il y a quelques bons articles sur la façon de le faire. Il suffit de les suivre, puis lorsque vous souhaitez ajouter une clé, utilisez les annotations de données pour "simuler" la clé.

Par exemple, disons que je connais ma table Orders, alors qu'il n'a pas de clé primaire, est assuré de n'avoir qu'un seul numéro de commande par client. Comme ce sont les deux premières colonnes de la table, je définirais les premières classes de code à ressembler à ceci:

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

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

En faisant cela, vous êtes fondamentalement truqué EF en croyant qu'il y a une clé en cluster composée de OrderNumber et Customer. Cela vous permettra de faire des insertions, des mises à jour, etc. sur votre table sans clé.

Si vous ne connaissez pas trop le code reverse, commencez par trouver un bon tutoriel sur Entity Framework Code First. Ensuite, allez en trouver un sur Reverse Code First (qui fait du Code First avec une base de données existante). Revenez ensuite ici et regardez à nouveau mes conseils clés. :)

Réponse originale:

Premièrement: comme d'autres l'ont dit, la meilleure option est d'ajouter une clé primaire à la table. Arrêt complet. Si vous pouvez le faire, ne lisez pas plus loin.

Mais si vous ne pouvez pas ou si vous vous détestez, il est possible 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 sur Access puis portés sur T-SQL). Donc je devais trouver un moyen. Ceci est ma solution. Les éléments suivants ont fonctionné pour moi en utilisant Entity Framework 6.0 (la dernière version de NuGet à ce jour).

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

  2. Recherchez une ligne comme celle-ci:
    <EntitySet Name="table_name" EntityType="MyModel.Store.table_name" store:Type="Tables" store:Schema="dbo" store:Name="table_nane">

  3. Retirer store:Name="table_name" à partir de la fin.

  4. Changement store:Schema="whatever" à Schema="whatever"

  5. Regardez ci-dessous cette ligne et trouvez le <DefiningQuery> marque. Il y aura une grande déclaration 'ol'. Retirez le tag et son contenu.

  6. Maintenant, votre ligne devrait ressembler à ceci:
    <EntitySet Name="table_name" EntityType="MyModel.Store.table_name" store:Type="Tables" Schema="dbo" />

  7. Nous avons autre chose à changer. Parcourez votre fichier et trouvez ceci:
    <EntityType Name="table_name">

  8. À proximité, vous verrez probablement un texte commenté vous avertissant qu'il n'a pas de clé primaire 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 effacé.

  9. Voici le <Key> marque. C'est ce que Entity Framework va utiliser pour faire insert / update / deletes. Donc, assurez-vous de faire ce droit. La propriété (ou les propriétés) de cette étiquette doit indiquer une ligne unique identifiable. Par exemple, disons que je connais ma table orders, alors qu'il n'a pas de clé primaire, est assuré de n'avoir qu'un seul numéro de commande par client.

Alors le mien ressemble à:

<EntityType Name="table_name">
              <Key>
                <PropertyRef Name="order_numbers" />
                <PropertyRef Name="customer_name" />
              </Key>

Sérieusement, ne le faites pas mal. Disons que même s'il ne doit jamais y avoir de doublons, deux lignes entrent dans mon système avec le même numéro de commande et le même nom de client. Whooops! C'est ce que je reçois pour ne pas utiliser une clé! J'utilise Entity Framework pour en supprimer un. Parce que je sais que le duplicata est le seul ordre mis aujourd'hui, je fais ceci:

var duplicateOrder = myModel.orders.First(x => x.order_date == DateTime.Today);
myModel.orders.Remove(duplicateOrder);

Devine quoi? Je viens de supprimer à la fois le doublon et l'original! C'est parce que j'ai dit à Entity Framework que numéro_de_commande / nom_de_coupe était ma clé primaire. Donc, quand je lui ai dit de supprimer duplicateOrder, ce qu'il a fait en arrière-plan était quelque chose comme:

DELETE FROM orders
WHERE order_number = (duplicateOrder's order number)
AND customer_name = (duplicateOrder's customer name)

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


27
2018-02-14 00:49



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

J'espère que cela va sauver la frustration de quelqu'un d'autre :)


18
2017-08-21 03:49



J'obtenais le même message d'erreur, mais dans mon scénario, j'essayais de mettre à jour les entités dérivées d'une relation many-to-many en utilisant un PJT (Pure Join Table).

En lisant les autres messages, j'ai pensé que je pourrais le réparer en ajoutant un champ PK supplémentaire à la table de jointure ... Cependant, si vous ajoutez une colonne PK à une table de jointure, ce n'est plus un PJT et vous perdez tous avantages du cadre d'entité comme le mappage de relation automatique entre les entités.

Donc la solution dans mon cas était de modifier la table de jointure sur la base de données pour faire un PK qui inclut les deux colonnes d'ID étrangères.


6
2018-01-23 18:00



une erreur peut survenir si votre table n'a pas de clé primaire, dans ce cas la table est en "lecture seule" et la commande db.SaveChanges () provoquera toujours une erreur


4
2018-01-25 15:33



donc c'est vrai, il suffit d'ajouter une clé primaire

Remarque: assurez-vous que lorsque vous mettez à jour votre diagramme EF à partir de la base de données, vous pointez vers le droite base de données, dans mon cas, la chaîne de connexion pointait vers une base de données locale au lieu de la DB à jour Dev, erreur d'écolier je sais, mais je voulais poster cela parce que cela peut être très frustrant si vous êtes convaincu ajouté la clé primaire et vous obtenez toujours la même erreur 


3
2018-02-25 07:28



J'ai eu le même problème. Comme ce sujet l’a dit, ma table n’avait pas de PK, alors j'ai défini le PK et exécuté le code. Mais malheureusement, l'erreur est revenue. Ce que j'ai fait ensuite était de supprimer la connexion DB (supprimer le fichier .edmx dans le dossier Model de Solution Explorer) et de le recréer. Erreur après cela. Merci à tous pour partager vos expériences. Cela fait gagner beaucoup de temps.


2
2018-04-06 06:49