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).
-
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.
-
Recherchez une ligne comme celle-ci:
-
Supprimez store:Nom="nom_table"
à la fin.
-
Changez store:Schéma="quelquechose"
en Schéma="quelquechose"
-
Recherchez en dessous de cette ligne et trouvez la balise . Elle contiendra une grande instruction select. Supprimez la balise et son contenu.
-
Maintenant votre ligne devrait ressembler à cela:
-
Nous avons quelque chose d'autre à changer. Parcourez votre fichier et trouvez ceci:
-
À 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é.
-
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 !
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)