Création d’un index unique avec une API fluide Entity Framework 6.1

J’ai une colonne “Nom” qui doit être unqiue. Aucune clé étrangère ou quelque chose comme ça.

EF 6.1 prend enfin en charge la création de tels index via Annotations. Cela a déjà été discuté sur SO. Mais il semble que cela ne peut se faire que par des annotations dans les classes. Comment est-ce que je fais cela en utilisant seulement l’API Fluent?

Quelque chose comme ça:

public class PersonConfiguration : EntityTypeConfiguration { public PersonConfiguration() { HasKey(p => p.Id); Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); //not possible? Index(p => p.Name).IsUnique(); //??? } } 

REMARQUE: Pertinent pour EF 6

Vous pouvez utiliser IndexAtsortingbute comme mentionné, mais avec l’ Fluent API au lieu de DataAnnotations ce qui fera l’affaire:

 modelBuilder .Entity() .Property(t => t.Name) .HasColumnAnnotation( "Index", new IndexAnnotation(new IndexAtsortingbute("IX_Name") { IsUnique = true })); 

Malheureusement, il n’y a pas d’autre moyen de créer des index uniques en utilisant l’ Fluent API . Il existe un problème en suspens concernant cette fonctionnalité: Contraintes uniques (Index uniques)


UPDATE: Entity Framework Core

Dans la dernière version d’EF Core, vous pouvez compter sur l’ Fluent API pour spécifier des index sans astuces supplémentaires.
HasIndex permet de le définir:

 modelBuilder .Entity() .HasIndex(x => x.Name); 

Par conséquent, il reprend l’object IndexBuilder vous pouvez utiliser pour d’autres configurations d’index (c.-à-d. Unicité):

 modelBuilder .Entity() .HasIndex(x => x.Name) .IsUnique(); 

Basé sur la réponse d’Anatolii, voici une méthode d’extension pour définir plus facilement des index uniques:

 public static class MappingExtensions { public static PrimitivePropertyConfiguration IsUnique(this PrimitivePropertyConfiguration configuration) { return configuration.HasColumnAnnotation("Index", new IndexAnnotation(new IndexAtsortingbute { IsUnique = true })); } } 

Usage:

 modelBuilder .Entity() .Property(t => t.Name) .IsUnique(); 

Générera une migration telle que:

 public partial class Add_unique_index : DbMigration { public override void Up() { CreateIndex("dbo.Person", "Name", unique: true); } public override void Down() { DropIndex("dbo.Person", new[] { "Name" }); } } 

Cette réponse ne contient que des informations supplémentaires car il existe déjà d’excellentes réponses.

Si vous souhaitez avoir plusieurs champs uniques dans votre index, vous pouvez y parvenir en ajoutant la propriété Order . Vous devez également vous assurer que vous utilisez le même nom d’index dans toutes vos propriétés (voir uniqueIndex ci-dessous).

 ssortingng uniqueIndex = "UN_TableName"; this.Property(t => t.PropertyOne) .HasColumnAnnotation( IndexAnnotation.AnnotationName, new IndexAnnotation( new IndexAtsortingbute(uniqueIndex) { IsUnique = true, Order = 1 } ) ); this.Property(t => t.PropertyTwo) .HasColumnAnnotation( IndexAnnotation.AnnotationName, new IndexAnnotation( new IndexAtsortingbute(uniqueIndex) { IsUnique = true, Order = 2 } ) ); 

Supposons maintenant que vous souhaitiez également un index sur PropertyTwo .

La mauvaise façon de le faire serait de commencer une nouvelle ligne avec this.Property(t => t.PropertyTwo) car cela this.Property(t => t.PropertyTwo) votre index unique.

Tous vos index (index et unique) doivent être définis en même temps. Ce serait la bonne façon de le faire:

 this.Property(t => t.PropertyTwo) .HasColumnAnnotation( IndexAnnotation.AnnotationName, new IndexAnnotation(new[] { new IndexAtsortingbute(), // This is the index new IndexAtsortingbute(uniqueIndex) // This is the Unique made earlier { IsUnique = true, Order = 2 } } ) ); 

Enfin, si vous souhaitez également modifier l’ordre de sorting de votre index / unique, vous pouvez voir:

Comment append un index sur plusieurs colonnes avec le sorting ASC / DESC à l’aide de l’API Fluent? .

Dans la nouvelle version d’EF 6.2, vous pouvez utiliser la méthode HasIndex :

  modelBuilder.Entity().HasIndex(user => user.Email).IsUnique(true); modelBuilder.Entity().HasIndex(user => user.UserName).IsUnique(true); 

Mise à jour pour EF Core:

  modelBuilder.Entity() .HasIndex(b => b.Email) .IsUnique(); modelBuilder.Entity() .HasIndex(b => b.UserName) .IsUnique(); 

Microsoft Docs – Index de base EF

Vous pouvez créer un index unique dans votre fichier de migration.

Dans le gestionnaire de paquets:

  1. Activer les migrations
  2. Add-Migration InitialMigration

Cela créera un nouveau fichier horodaté dans votre dossier Migrations. La classe aura une méthode Up and Down que vous pouvez utiliser pour créer l’index:

 public override void Up() { // ... CreateIndex("tableName", "columnName", unique: true, name: "myIndex"); } public override void Down() { // ... DropIndex("tableName", "myIndex"); } 

Pour exécuter la migration, tapez Update-Database dans le gestionnaire de packages.

Vous pouvez également append l’index dans le cadre de la migration qui crée la table:

 CreateTable( "dbo.Products", c => new { ProductId = c.Int(nullable: false, identity: true), ProductName = c.Ssortingng(nullable: false, maxLength: 256), }) .Index(c => c.ProductName, name: "IX_Products_ProductName", unique: true) .PrimaryKey(t => t.ProductId); 

Pour moi, en utilisant MVC 5 et EF 6, le point clé était de spécifier une longueur sur la propriété ssortingng où je voulais placer l’index.

 protected override void OnModelCreating(DbModelBuilder modelBuilder){ //More stuff modelBuilder.Entity().Property(c => c.Name).HasColumnType("nvarchar").HasMaxLength(50); modelBuilder.Entity().HasIndex(c => c.Name).IsUnique(true); }