web-dev-qa-db-fra.com

Comment créer un index dans Entity Framework 6.2 avec un code en premier

Existe-t-il un moyen de créer un index sur une propriété/une colonne en utilisant code-first au lieu d'utiliser le nouveau IndexAttribute ?

100
Valo

Eh bien 26.10.2017 Entity Framework 6.2 était officiellement publié . Il inclut un possibilité pour définir facilement les index via l'API Fluent. Ho il est à utiliser était déjà annoncé dans la version bêta de 6.2.

Vous pouvez maintenant utiliser la méthode HasIndex(), suivie de IsUnique() s'il doit s'agir d'un index unique.

Juste une petite comparaison (avant/après) exemple:

// before 
modelBuilder.Entity<Person>()
        .Property(e => e.Name)
        .HasColumnAnnotation(
            IndexAnnotation.AnnotationName, 
            new IndexAnnotation(new IndexAttribute { IsUnique = true }));

// after
modelBuilder.Entity<Person>()
    .HasIndex(p => p.Name)
    .IsUnique();

// multi column index
modelBuilder.Entity<Person>()
    .HasIndex(p => new { p.Name, p.Firstname })
    .IsUnique();

Il est également possible de marquer l'index comme étant en cluster avec .IsClustered().


EDIT # 1

Ajout d'un exemple d'index multi-colonnes et d'informations supplémentaires sur la manière de marquer un index comme étant en cluster.


EDIT # 2

En tant qu'informations supplémentaires, dans EF Core 2.1, c'est exactement la même chose que dans EF 6.2.
Ici est le MS Doc artcile comme référence.

68
ChW

Actuellement, il n'y a pas de "support de première classe" pour la création d'un index via l'API fluide, mais vous pouvez le faire via l'API fluide, vous pouvez marquer les propriétés comme ayant des attributs de l'API d'annotation. Cela vous permettra d'ajouter l'attribut Index via une interface fluide.

Voici quelques exemples tirés de l’élément de travail du site Problèmes pour EF.

Créez un index sur une seule colonne:

modelBuilder.Entity<MyEntity>()
    .Property(e => e.MyProperty)
    .HasColumnAnnotation(
        IndexAnnotation.AnnotationName, 
        new IndexAnnotation(new IndexAttribute()));

Plusieurs index sur une seule colonne:

modelBuilder.Entity<MyEntity>()
    .Property(e => e.MyProperty)
    .HasColumnAnnotation(
        IndexAnnotation.AnnotationName, 
        new IndexAnnotation(new[]
            {
                new IndexAttribute("Index1"),
                new IndexAttribute("Index2") { IsUnique = true }
            }));

Index multi-colonnes:

modelBuilder.Entity<MyEntity>()
    .Property(e => e.MyProperty1)
    .HasColumnAnnotation(
        IndexAnnotation.AnnotationName,
        new IndexAnnotation(new IndexAttribute("MyIndex", 1)));

modelBuilder.Entity<MyEntity>()
    .Property(e => e.MyProperty2)
    .HasColumnAnnotation(
        IndexAnnotation.AnnotationName, 
        new IndexAnnotation(new IndexAttribute("MyIndex", 2)));

En utilisant les techniques ci-dessus, les appels .CreateIndex() seront automatiquement créés pour vous dans votre fonction Up() lorsque vous échafauderez votre prochaine migration (ou seront automatiquement créés dans la base de données si vous n'utilisez pas de migrations).

84
Scott Chamberlain

J'ai créé quelques méthodes d'extension et les ai emballées dans un paquet de pépites pour rendre cela beaucoup plus facile.

Installez le package EntityFramework.IndexingExtensions .

Ensuite, vous pouvez faire ce qui suit:

_public class MyDataContext : DbContext
{
  protected override void OnModelCreating(DbModelBuilder modelBuilder)
  {
    modelBuilder.Entity<Customer>()
        .HasIndex("IX_Customers_Name",          // Provide the index name.
            e => e.Property(x => x.LastName),   // Specify at least one column.
            e => e.Property(x => x.FirstName))  // Multiple columns as desired.

        .HasIndex("IX_Customers_EmailAddress",  // Supports fluent chaining for more indexes.
            IndexOptions.Unique,                // Supports flags for unique and clustered.
            e => e.Property(x => x.EmailAddress)); 
  }
}
_

Le projet et le code source sont ici . Prendre plaisir!

36
Matt Johnson-Pint

Sans nom explicite:

[Index]
public int Rating { get; set; } 

Avec un nom spécifique:

[Index("PostRatingIndex")] 
public int Rating { get; set; }
19
Hugo Hilário

A partir de EF 6.1, l'attribut [Index] est pris en charge.
Utilisez [Index(IsUnique = true)] pour un index unique.
Voici le lien de Microsoft

public class User 
{ 
    public int UserId { get; set; } 

    [Index(IsUnique = true)] 
    [StringLength(200)] 
    public string Username { get; set; } 

    public string DisplayName { get; set; } 
}
15
Darie Dorlus

Entity Framework 6

Property(c => c.MyColumn)
        .HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("IX_MyIndex")));

Et ajoutez en utilisant:

using System.Data.Entity.Infrastructure.Annotations;
using System.ComponentModel.DataAnnotations.Schema;
8
Guilherme Ferreira

Vous pouvez utiliser l’annotation de données INDEX Code First Data Annotations

6
Emre

Si vous ne souhaitez pas utiliser d'attributs sur vos POCO, vous pouvez toujours le faire comme suit:

context.Database.ExecuteSqlCommand("CREATE INDEX IX_NAME ON ..."); 

Vous pouvez exécuter cette instruction dans votre classe dérivée personnalisée DbInitializer. Cependant, je ne connais aucune façon de faire cela avec l'API Fluent.

2
Mert Akcakaya

Vous pouvez utiliser l'un de ces

// index

 this.HasIndex(e => e.IsActive)
            .HasName("IX_IsActive");

ou

  this.Property(e => e.IsActive).HasColumnAnnotation(
            "Index",
            new IndexAnnotation(new IndexAttribute("IX_IsActive")));
1
Nayas Subramanian

J'écris une méthode d'extension à utiliser dans EF fluide pour éviter le code supplémentaire:

public static PrimitivePropertyConfiguration HasIndexAnnotation(
    this PrimitivePropertyConfiguration primitivePropertyConfiguration, 
    IndexAttribute indexAttribute = null
    )
{
    indexAttribute = indexAttribute ?? new IndexAttribute();

    return primitivePropertyConfiguration
        .HasColumnAnnotation(
            IndexAnnotation.AnnotationName, 
            new IndexAnnotation(indexAttribute)
        );
}

puis utilisez-le comme ceci:

Property(t => t.CardNo)
    .HasIndexAnnotation();

ou comme ceci si index a besoin de configs:

Property(t => t.CardNo)
    .HasIndexAnnotation(new IndexAttribute("IX_Account") { IsUnique = true });
1
Omid-RH