J'utilise d'abord le code Entity Framework 5.0;
public class Entity
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public string EntityId { get; set;}
public int FirstColumn { get; set;}
public int SecondColumn { get; set;}
}
Je veux rendre la combinaison entre FirstColumn
et SecondColumn
aussi unique.
Exemple:
Id FirstColumn SecondColumn
1 1 1 = OK
2 2 1 = OK
3 3 3 = OK
5 3 1 = THIS OK
4 3 3 = GRRRRR! HERE ERROR
Y'a-t'il un quelconque moyen d'y arriver?
entity-framework
ef-code-first
constraints
multiple-columns
unique-key
Bassam Alugili
la source
la source
J'ai trouvé trois façons de résoudre le problème.
Index uniques dans EntityFramework Core:
Première approche:
La seconde approche pour créer des contraintes uniques avec EF Core en utilisant des clés alternatives.
Exemples
Une colonne:
Plusieurs colonnes:
EF 6 et inférieurs:
Première approche:
Cette approche est très rapide et utile mais le principal problème est qu'Entity Framework ne sait rien de ces changements!
Deuxième approche:
je l'ai trouvé dans ce post mais je n'ai pas essayé par moi-même.
Le problème de cette approche est le suivant: elle a besoin de DbMigration, alors que faites-vous si vous ne l'avez pas?
Troisième approche:
je pense que c'est la meilleure mais cela demande du temps. Je vais juste vous montrer l'idée derrière cela: Dans ce lien http://code.msdn.microsoft.com/CSASPNETUniqueConstraintInE-d357224a, vous pouvez trouver le code d'annotation de données de clé unique:
Le problème de cette approche; Comment puis-je les combiner? J'ai une idée d'étendre cette implémentation Microsoft par exemple:
Plus loin dans IDatabaseInitializer comme décrit dans l'exemple Microsoft, vous pouvez combiner les clés en fonction de l'entier donné. Une chose doit être notée cependant: si la propriété unique est de type chaîne, vous devez définir la longueur maximale.
la source
CREATE UNIQUE INDEX ix_{1}_{2} ON {0} ({1}, {2})
:? (voir BOL )Si vous utilisez Code-First , vous pouvez implémenter une extension personnalisée HasUniqueIndexAnnotation
Ensuite, utilisez-le comme ceci:
Ce qui entraînera cette migration:
Et finalement finir dans la base de données comme:
la source
this.Property(t => t.Email)
), quelle est cette classe contenant? (c.-à-d. ce qui estthis
)EntityTypeConfiguration<T>
Vous devez définir une clé composite.
Avec les annotations de données, cela ressemble à ceci:
Vous pouvez également le faire avec modelBuilder lors de la substitution de OnModelCreating en spécifiant:
la source
La réponse de niaher indiquant que pour utiliser l'API fluide, vous avez besoin d'une extension personnalisée peut-être correcte au moment de la rédaction. Vous pouvez maintenant (EF core 2.1) utiliser l'API couramment comme suit:
la source
Compléter la réponse @chuck pour utiliser des indices composites avec des clés étrangères .
Vous devez définir une propriété qui contiendra la valeur de la clé étrangère. Vous pouvez ensuite utiliser cette propriété dans la définition d'index.
Par exemple, nous avons une entreprise avec des employés et seulement nous avons une contrainte unique sur (nom, entreprise) pour tout employé:
Maintenant, le mappage de la classe Employee:
Notez que j'ai également utilisé l'extension @niaher pour l'annotation d'index unique.
la source
Dans la réponse acceptée par @chuck, il y a un commentaire disant que cela ne fonctionnera pas dans le cas de FK.
cela a fonctionné pour moi, cas de EF6 .Net4.7.2
la source
Je suppose que vous voulez toujours
EntityId
être la clé primaire, donc la remplacer par une clé composite n'est pas une option (ne serait-ce que parce que les clés composites sont beaucoup plus compliquées à utiliser et à utiliser parce qu'il n'est pas très judicieux d'avoir des clés primaires qui ont également un sens dans la logique métier).Le moins que vous puissiez faire est de créer une clé unique sur les deux champs de la base de données et de vérifier spécifiquement les exceptions de violation de clé unique lors de l'enregistrement des modifications.
De plus, vous pouvez (devriez) vérifier les valeurs uniques avant d'enregistrer les modifications. La meilleure façon de le faire est par une
Any()
requête, car elle minimise la quantité de données transférées:Attention, ce chèque à lui seul n'est jamais suffisant. Il y a toujours une certaine latence entre la vérification et la validation réelle, vous aurez donc toujours besoin de la gestion unique des contraintes et des exceptions.
la source
Récemment ajouté une clé composite avec l'unicité de 2 colonnes en utilisant l'approche recommandée par 'chuck', merci @chuck. Seule cette approche m'a paru plus propre:
la source