webentwicklung-frage-antwort-db.com.de

Wie erstelle ich einen Index in Entity Framework 6.2 mit Code?

Gibt es eine Möglichkeit, einen Index für eine Eigenschaft/Spalte mit Code-First zu erstellen, anstatt das neue IndexAttribute zu verwenden?

100
Valo

Nun 26.10.2017 Entity Framework 6.2 war offiziell freigegeben . Es enthält eine Möglichkeit um Indizes einfach über die Fluent API zu definieren. Wie es zu gebrauchen war angekündigt in der Beta von 6.2.

Jetzt können Sie die Methode HasIndex() verwenden, gefolgt von IsUnique(), wenn es sich um einen eindeutigen Index handeln soll.

Nur ein kleines Vergleichsbeispiel (vorher/nachher):

// 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();

Es ist auch möglich, den Index mit .IsClustered() als gruppiert zu markieren.


EDIT # 1

Ein Beispiel für einen mehrspaltigen Index und zusätzliche Informationen zum Markieren eines Index als gruppiert wurde hinzugefügt.


EDIT # 2

Als zusätzliche Information ist es in EF Core 2.1 genau das gleiche wie in EF 6.2.
hier ist das MS Doc-Dokument als Referenz.

68
ChW

Derzeit gibt es kein "First Class Support" zum Erstellen eines Indexes über die Fluent-API. Sie können Eigenschaften jedoch über die Fluent-API als Attribute der Annotation-API kennzeichnen. Auf diese Weise können Sie das Attribut Index über eine flüssige Schnittstelle hinzufügen.

Hier einige Beispiele aus dem Arbeitselement von der Issues-Site für EF.

Erstellen Sie einen Index für eine einzelne Spalte:

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

Mehrere Indizes für eine einzelne Spalte:

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

Mehrspaltige Indizes:

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)));

Wenn Sie die oben genannten Techniken verwenden, werden .CreateIndex() Aufrufe automatisch für Sie in Ihrer Up() Funktion erstellt, wenn Sie Ihre nächste Migration planen (oder werden automatisch in der Datenbank erstellt, wenn Sie keine Migrationen verwenden ).

84

Ich habe einige Erweiterungsmethoden erstellt und sie in ein Nuget-Paket eingepackt, um dies zu vereinfachen.

Installiere das EntityFramework.IndexingExtensions Nuget-Paket.

Dann können Sie Folgendes tun:

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)); 
  }
}

Das Projekt und der Quellcode sind hier . Genießen!

36

Ohne expliziten Namen:

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

Mit einem bestimmten Namen:

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

Ab EF 6.1 wird das Attribut [Index] Unterstützt.
Verwenden Sie [Index(IsUnique = true)] für einen eindeutigen Index.
Hier ist der Link von 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")));

Und füge hinzu mit:

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

Sie können die INDEX-Datenanmerkung Code First Data Annotations verwenden

6
Emre

Wenn Sie keine Attribute für Ihre POCOs verwenden möchten, können Sie dies immer wie folgt tun:

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

Sie können diese Anweisung in Ihrer benutzerdefinierten DbInitializer abgeleiteten Klasse ausführen. Ich kenne jedoch keine Fluent API-Methode, um dies zu tun.

2
Mert Akcakaya

Sie können eines davon verwenden

// Indizes

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

oder

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

Ich schreibe eine Erweiterungsmethode für die Verwendung in fließendem EF, um zusätzlichen Code zu vermeiden:

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

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

dann benutze es so:

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

oder wie folgt, wenn index einige configs benötigt:

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