Gibt es eine Möglichkeit, einen Index für eine Eigenschaft / Spalte mit Code-First zu erstellen, anstatt den neuen zu verwenden IndexAttribute
?
Gibt es eine Möglichkeit, einen Index für eine Eigenschaft / Spalte mit Code-First zu erstellen, anstatt den neuen zu verwenden IndexAttribute
?
Antworten:
Nun, 26.10.2017 Entity Framework 6.2 wurde offiziell veröffentlicht . Es bietet die Möglichkeit , Indizes einfach über die Fluent API zu definieren. Wie es zu verwenden ist, wurde bereits in der Beta von 6.2 angekündigt .
Jetzt können Sie die HasIndex()
Methode verwenden, gefolgt von der Frage, IsUnique()
ob es sich um einen eindeutigen Index handeln soll.
Nur ein kleiner Vergleich (vorher / nachher) Beispiel:
// 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 als gruppiert mit zu markieren .IsClustered()
.
EDIT # 1
Es wurde ein Beispiel für einen mehrspaltigen Index und zusätzliche Informationen zum Markieren eines Index als Cluster 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 der MS Doc Artcile als Referenz.
new
. Ich werde es reparieren.
Derzeit gibt es keine "erstklassige Unterstützung" für die Erstellung eines Index über die fließende API. Sie können jedoch über die fließende API Eigenschaften als Attribute aus der Annotation-API markieren. Auf diese Weise können Sie das Index
Attribut über eine fließende Schnittstelle hinzufügen .
Hier sind 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 beim Erstellen Ihrer nächsten Migration .CreateIndex()
automatisch Aufrufe für Sie in Ihrer Up()
Funktion erstellt (oder automatisch in der Datenbank erstellt, wenn Sie keine Migrationen verwenden).
.Primarykey(x=>x.id,clustered:false)
method
HasAnnotation
Methode ausprobiert und es gibt KEINE solche Methode. Aber ich habe eine Methode gefunden, deren Name HasColumnAnnotation
die von Ihnen angegebenen Parameter akzeptiert. Müssen Sie Ihre Antwort aktualisieren oder irre ich mich?
Ich habe einige Erweiterungsmethoden erstellt und sie in ein Nuget-Paket eingeschlossen, um dies viel einfacher zu machen.
Installieren Sie 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!
IndexAttribute
Klasse nicht verfügbar gemacht , sodass ich es nicht in meine Bibliothek aufnehmen kann.
Ohne expliziten Namen:
[Index]
public int Rating { get; set; }
Mit einem bestimmten Namen:
[Index("PostRatingIndex")]
public int Rating { get; set; }
EntityFramework
. Es ist in dieser Baugruppe enthalten. nur verwirrt über die NS.
instead of using the new IndexAttribute
Haben Sie es bemerkt?
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; }
}
[Index("IX_BlogIdAndRating", 2)]
public int Rating { get; set; }
[Index("IX_BlogIdAndRating", 1)]
public int BlogId { get; set; }
hier die Referenz von Microsoft
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;
Sie können den INDEX-Datenanmerkungscode First Data Annotations verwenden
Wenn Sie keine Attribute für Ihre POCOs verwenden möchten, können Sie dies jederzeit 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.
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 so, wenn der Index einige Konfigurationen benötigt:
Property(t => t.CardNo)
.HasIndexAnnotation(new IndexAttribute("IX_Account") { IsUnique = true });
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")));