J'ai une base de données existante avec laquelle je voudrais créer une nouvelle application en utilisant EF4.0
Certaines tables n'ont pas de clés primaires définies, de sorte que lorsque je crée un nouveau modèle de données d'entité, j'obtiens le message suivant:
The table/view TABLE_NAME does not have a primary key defined
and no valid primary key could be inferred. This table/view has
been excluded. To use the entity, you will need to review your schema,
add the correct keys, and uncomment it.
Si je veux les utiliser et modifier les données, dois-je nécessairement ajouter un PK à ces tables, ou existe-t-il une solution de contournement pour ne pas avoir à le faire?
Réponses:
L'erreur signifie exactement ce qu'elle dit.
Même si vous pouviez contourner ce problème, croyez-moi, vous ne le voulez pas. Le nombre de bugs déroutants qui pourraient être introduits est stupéfiant et effrayant, sans parler du fait que votre performance passera probablement dans les tubes.
Ne contournez pas ça. Corrigez votre modèle de données.
EDIT: J'ai vu qu'un certain nombre de personnes votent contre cette question. C'est bien, je suppose, mais gardez à l'esprit que l'OP a demandé à mapper une table sans clé primaire, pas une vue . La réponse est toujours la même. Contourner le besoin de l'EF d'avoir une PK sur les tables est une mauvaise idée du point de vue de la gérabilité, de l'intégrité des données et des performances.
Certains ont indiqué qu'ils n'avaient pas la possibilité de réparer le modèle de données sous-jacent car ils étaient mappés à une application tierce. Ce n'est pas une bonne idée, car le modèle peut changer sous vous. On peut soutenir que dans ce cas, vous voudriez mapper sur une vue, ce qui, encore une fois, n'est pas ce que le PO a demandé.
la source
Je pense que cela est résolu par Tillito:
Entity Framework et vue SQL Server
Je vais citer son entrée ci-dessous:
Nous avons eu le même problème et voici la solution:
Pour forcer la structure d'entité à utiliser une colonne comme clé primaire, utilisez ISNULL.
Pour forcer la structure d'entité à ne pas utiliser une colonne comme clé primaire, utilisez NULLIF.
Un moyen simple d'appliquer ceci est d'encapsuler l'instruction select de votre vue dans un autre select.
Exemple:
26 avr. 10 à 17:00 par Tillito
la source
Pour ceux qui atteignent cette question et utilisent Entity Framework Core, vous n'avez plus nécessairement besoin d'ajouter un PK à ces tables ou de faire une solution de contournement. Depuis EF Core 2.1, nous avons une nouvelle fonctionnalité Types de requêtes
Les types de requête doivent être utilisés pour:
Donc, dans votre DbContext, ajoutez simplement la propriété suivante de type
DbQuery<T>
au lieu deDbSet<T>
celle ci-dessous. En supposant que le nom de votre table estMyTable
:la source
Les clés composites peuvent également être créées avec l'API Entity Framework Fluent
la source
modelBuilder.Entity<T>()
appel en chaîne avec.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None)
pour ces clés si spéciales qui ne sont pas naturelles ou composites, mais qui peuvent être fiables être unique (généralement, de toute façon.)Dans mon cas, j'ai dû mapper une entité à une vue, qui n'avait pas de clé primaire. De plus, je n'étais pas autorisé à modifier cette vue. Heureusement, cette vue avait une colonne qui était une chaîne unique. Ma solution était de marquer cette colonne comme clé primaire:
EF trompé. A parfaitement fonctionné, personne n'a remarqué ... :)
la source
UserID
colonne si vous utilisez l'approche Code First ..!Itentity
fonction. Fondamentalement, si j'ai raison, cela va toujours créer uneUserID
colonne pour vous en tant que PK, mais cela n'augmentera pas automatiquementUserID
lorsque vous créez un nouvel enregistrement comme le serait par défaut. En outre, vous devez toujours conserver des valeurs distinctes dansUserID
.EF ne nécessite pas de clé primaire sur la base de données. Si tel était le cas, vous ne pouviez pas lier les entités aux vues.
Vous pouvez modifier le SSDL (et le CSDL) pour spécifier un champ unique comme clé primaire. Si vous n'avez pas de champ unique, alors je crois que vous êtes arrosé. Mais vous devriez vraiment avoir un champ unique (et un PK), sinon vous allez rencontrer des problèmes plus tard.
Erick
la source
Avoir une clé d'identité inutile est parfois inutile. Je trouve que si l'identifiant n'est pas utilisé, pourquoi l'ajouter? Cependant, Entity ne pardonne pas trop, donc ajouter un champ ID serait préférable. Même dans le cas où il n'est pas utilisé, c'est mieux que de traiter les erreurs incessantes d'Entity concernant la clé d'identité manquante.
la source
CETTE SOLUTION FONCTIONNE
Vous n'avez pas besoin de mapper manuellement même si vous n'avez pas de PK. Il vous suffit d'indiquer à l'EF que l'une de vos colonnes est index et que la colonne d'index n'est pas nullable.
Pour ce faire, vous pouvez ajouter un numéro de ligne à votre vue avec la fonction isNull comme suit
ISNULL(id, number)
est le point clé ici car il indique à l'EF que cette colonne peut être la clé primairela source
Les réponses ci-dessus sont correctes si vous n'avez vraiment pas de PK.
Mais s'il y en a un mais qu'il n'est tout simplement pas spécifié avec un index dans la base de données, et que vous ne pouvez pas changer la base de données (oui, je travaille dans le monde de Dilbert), vous pouvez mapper manuellement le (s) champ (s) pour être la clé.
la source
Ceci est juste un ajout à la réponse de @Erick T. S'il n'y a pas de colonne unique avec des valeurs uniques, la solution de contournement consiste à utiliser une clé composite, comme suit:
Encore une fois, ce n'est qu'une solution de contournement. La vraie solution est de corriger le modèle de données.
la source
C'est peut-être trop tard pour répondre ... cependant ...
Si une table n'a pas de clé primaire, il existe peu de scénarios qui doivent être analysés pour que l'EF fonctionne correctement. La règle est la suivante: EF fonctionnera avec des tables / classes avec une clé primaire. C'est ainsi qu'il effectue le suivi ...
Disons, votre table 1. Les enregistrements sont uniques: l'unicité est faite par une seule colonne de clé étrangère: 2. Les enregistrements sont uniques: l'unicité est faite par une combinaison de plusieurs colonnes. 3. Les enregistrements ne sont pas uniques (pour la plupart *).
Pour les scénarios n ° 1 et n ° 2, vous pouvez ajouter la ligne suivante à la méthode OnModelCreating du module DbContext: modelBuilder.Entity (). HasKey (x => new {x.column_a, x.column_b}); // autant de colonnes que nécessaire pour rendre les enregistrements uniques.
Pour le scénario n ° 3, vous pouvez toujours utiliser la solution ci-dessus (n ° 1 + n ° 2) après avoir étudié la table (* ce qui rend tous les enregistrements uniques de toute façon). Si vous devez inclure TOUTES les colonnes pour rendre tous les enregistrements uniques, vous pouvez ajouter une colonne de clé primaire à votre table. Si cette table provient d'un fournisseur tiers, clonez cette table dans votre base de données locale (pendant la nuit ou autant de fois que vous en avez besoin) avec la colonne de clé primaire ajoutée de manière arbitraire via votre script de clonage.
la source
Entity Framework: ajout de DataTable sans clé primaire au modèle d'entité.
la source
Mettez à jour la réponse de @CodeNotFound .
Dans EF Core 3.0
DbQuery<T>
est obsolète, vous devez à la place utiliser des types d'entité Keyless qui font supposément la même chose. Ceux-ci sont configurés avec laHasNoKey()
méthode ModelBuilder . Dans votre classe DbContext, faites ceciIl existe cependant des restrictions, notamment:
Cela signifie que pour la question de
Vous ne pouvez pas modifier les données de cette façon - cependant vous pouvez lire. On pourrait cependant envisager d'utiliser une autre méthode (par exemple ADO.NET, Dapper) pour modifier les données - cela pourrait être une solution dans les cas où vous avez rarement besoin de faire des opérations sans lecture et que vous souhaitez toujours vous en tenir à EF Core dans vos cas majoritaires.
De plus, si vous avez vraiment besoin / souhaitez travailler avec des tables de tas (sans clé), envisagez d'abandonner EF et utilisez une autre façon de communiquer avec votre base de données.
la source
D'un point de vue pratique, chaque table - même une table dénormalisée comme une table d'entrepôt - doit avoir une clé primaire. Ou, à défaut, il devrait au moins avoir un index unique, non nullable.
Sans une sorte de clé unique, des enregistrements en double peuvent (et apparaîtront) apparaître dans le tableau, ce qui est très problématique à la fois pour les couches ORM et aussi pour la compréhension de base des données. Une table contenant des enregistrements en double est probablement le symptôme d'une mauvaise conception.
À tout le moins, la table doit au moins avoir une colonne d'identité. L'ajout d'une colonne d'ID à génération automatique prend environ 2 minutes dans SQL Server et 5 minutes dans Oracle. Pour cet effort supplémentaire, de nombreux problèmes seront évités.
la source
Nous avons également rencontré ce problème et, bien que nous ayons une colonne contenant des valeurs nulles, ce qui était important, c'était que nous ayons une colonne dépendante qui n'avait pas de valeurs nulles et que la combinaison de ces deux colonnes était unique.
Donc, pour citer la réponse de Pratap Reddy, cela a bien fonctionné pour nous.
la source
Je suis très heureux que mon problème soit résolu.
Impossible de mettre à jour EntitySet - car il a un DefiningQuery et aucun élément <UpdateFunction> n'existe
et faites ceci: Regardez en dessous de cette ligne et trouvez l'étiquette. Il contiendra une grande instruction select. Supprimez la balise et son contenu.
maintenant sans changer DB TI peut insérer dans une table qui n'a pas PK
merci à tous et merci Pharylon
la source
Dans EF Core 5.0, vous pourrez également le définir au niveau de l'entité.
Référence: https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-5.0/whatsnew#use-ac-attribute-to-indicate-that-an-entity- n'a pas de clé
la source
La table doit juste avoir une colonne qui n'autorise pas les valeurs nulles
la source