Définition d'une contrainte unique avec une API fluide?
185
J'essaie de créer une entité EF avec Code First et une EntityTypeConfigurationAPI fluide. la création de clés primaires est facile, mais pas avec une contrainte unique. Je voyais d'anciens articles suggérant d'exécuter des commandes SQL natives pour cela, mais cela semble aller à l'encontre de l'objectif. est-ce possible avec EF6?
Voici un exemple plus réaliste. Il ajoute un index unique sur plusieurs propriétés: User.FirstNameet User.LastName, avec un nom d'index "IX_FirstNameLastName"
Ceci est nécessaire pour nommer l'annotation de colonne comme "Index"! J'ai écrit un autre nom et ça n'a pas marché! J'ai passé des heures avant d'essayer de le renommer en "Index" d'origine comme dans votre message et j'ai compris que c'était important. :( Il doit y avoir une constante dans le cadre pour ne pas coder en dur la chaîne.
Alexander Vasilyev
10
@AlexanderVasilyev La constante est définie commeIndexAnnotation.AnnotationName
Nathan
3
@Nathan Merci! C'est tout! L'exemple de cet article doit être corrigé en utilisant cette constante.
Alexander Vasilyev
2
Je n'arrive pas à le trouver dans EF7 - DNX
Shimmy Weitzhandler
2
Je crois que IsUnique doit être défini sur true lors de la création d'IndexAttribute dans le premier exemple. Comme ceci: new IndexAttribute() { IsUnique = true }. Sinon, il crée juste un index régulier (non unique).
jakubka
134
En plus de la réponse de Yorro, cela peut également être fait en utilisant des attributs.
Exemple de intcombinaison de touches de type unique:
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
namespace EFIndexTest{classProgram{staticvoidMain(string[] args){
using (var context =newAppDbContext()){var newUser =newUser{UniqueKeyIntPart1=1,UniqueKeyIntPart2=1,UniqueKeyStringPart1="A",UniqueKeyStringPart2="A"};
context.UserSet.Add(newUser);
context.SaveChanges();}}}[MetadataType(typeof(UserMetadata))]publicclassUser{publicintId{get;set;}publicintUniqueKeyIntPart1{get;set;}publicintUniqueKeyIntPart2{get;set;}publicstringUniqueKeyStringPart1{get;set;}publicstringUniqueKeyStringPart2{get;set;}}publicclassUserMetadata{[Index("IX_UniqueKeyInt",IsUnique=true,Order=1)]publicintUniqueKeyIntPart1{get;set;}[Index("IX_UniqueKeyInt",IsUnique=true,Order=2)]publicintUniqueKeyIntPart2{get;set;}[Index("IX_UniqueKeyString",IsUnique=true,Order=1)][MaxLength(50)]publicstringUniqueKeyStringPart1{get;set;}[Index("IX_UniqueKeyString",IsUnique=true,Order=2)][MaxLength(50)]publicstringUniqueKeyStringPart2{get;set;}}publicclassAppDbContext:DbContext{publicvirtualDbSet<User>UserSet{get;set;}}}
Pas si vous voulez garder votre modèle de domaine complètement séparé des problèmes de stockage.
Rickard Liljeberg
4
Vous devez également vous assurer d'avoir une référence à EntityFramework
Michael Tranchida
2
Soyez gentil si l'attribut Index était séparé de Entity Framework afin que je puisse l'inclure dans mon projet Models. Je comprends que c'est un problème de stockage, mais la principale raison pour laquelle je l'utilise est de mettre des contraintes uniques sur des éléments tels que les noms d'utilisateur et les noms de rôle.
Sam le
2
Je n'arrive pas à le trouver dans EF7 - DNX
Shimmy Weitzhandler
4
Cela ne fonctionne que si vous limitez également la longueur de la chaîne, car SQL n'autorise pas l'utilisation de nvarchar (max) comme clé.
JMK le
17
Voici une méthode d'extension pour définir plus couramment des index uniques:
La réponse de @ coni2k est correcte mais vous devez ajouter un [StringLength]attribut pour que cela fonctionne sinon vous obtiendrez une exception de clé non valide (exemple ci-dessous).
IndexAnnotation.AnnotationName
new IndexAttribute() { IsUnique = true }
. Sinon, il crée juste un index régulier (non unique).En plus de la réponse de Yorro, cela peut également être fait en utilisant des attributs.
Exemple de
int
combinaison de touches de type unique:Si le type de données est
string
, l'MaxLength
attribut doit être ajouté:S'il y a un problème de séparation de domaine / modèle de stockage, l'utilisation d'
Metadatatype
attribut / classe peut être une option: https://msdn.microsoft.com/en-us/library/ff664465%28v=pandp.50%29.aspx?f= 255 & MSPPError = -2147217396Un exemple d'application de console rapide:
la source
Voici une méthode d'extension pour définir plus couramment des index uniques:
Usage:
Générera des migrations telles que:
Src: Création d'un index unique avec l'API Fluent Entity Framework 6.1
la source
La réponse de @ coni2k est correcte mais vous devez ajouter un
[StringLength]
attribut pour que cela fonctionne sinon vous obtiendrez une exception de clé non valide (exemple ci-dessous).la source
Malheureusement, cela n'est pas pris en charge dans Entity Framework. C'était sur la feuille de route pour EF 6, mais il a été repoussé: Élément de travail 299: contraintes uniques (index uniques)
la source
la source