2014-06-21 5 views
15

Es sieht so aus, als ob in Entity Framework 6.1 die Möglichkeit hinzugefügt wurde, Tabellenindizes über die neue Methode HasColumnAnnotation zu erstellen. Ich habe ein paar Helfer Erweiterungen um den Prozess zu beschleunigen:Mehrere Indizes möglich mit HasColumnAnnotation?

public static class MappingExtensions 
{ 
    public static StringPropertyConfiguration HasIndex(this StringPropertyConfiguration config, bool isUnique = false) 
    { 
     return config.HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute() { IsUnique = isUnique })); 
    } 
    public static StringPropertyConfiguration HasIndex(this StringPropertyConfiguration config, string name, int order = 1, bool isUnique = false) 
    { 
     return config.HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute(name, order) { IsUnique = isUnique })); 
    } 
    public static PrimitivePropertyConfiguration HasIndex(this PrimitivePropertyConfiguration config, bool isUnique = false) 
    { 
     return config.HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute() { IsUnique = isUnique })); 
    } 
    public static PrimitivePropertyConfiguration HasIndex(this PrimitivePropertyConfiguration config, string name, int order = 1, bool isUnique = false) 
    { 
     return config.HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute(name, order) { IsUnique = isUnique })); 
    } 
} 

Dieses fantastische funktioniert ... bis ich versuche, einen zweiten Index zu erstellen, die eine Spalte bereits in einem anderen Index verwendet wird, enthält. Was immer ich hinzufüge, überschreibt das Original. Weiß jemand, ob es derzeit möglich ist, der gleichen Spalte mehrere Indizes über die neue HasColumnAnnotation hinzuzufügen, die auf der StringPropertyConfiguration und PrimitivePropertyConfiguration verfügbar ist?

Ich kann das umgehen, wie ich es immer durch manuelle Hinzufügen von Indexen in den Migrationsskripten habe, aber es wäre am besten, dies in den EntityTypeConfiguration Zuordnungen zu konfigurieren, damit ich alles an einem Ort haben kann.


Nach Gerts Feedback, das ist, was ich tun endete:

public static class MappingExtensions 
{ 
    public static StringPropertyConfiguration HasIndex(this StringPropertyConfiguration config, params IndexAttribute[] indexes) 
    { 
     return config.HasColumnAnnotation("Index", new IndexAnnotation(indexes)); 
    } 

    public static PrimitivePropertyConfiguration HasIndex(this PrimitivePropertyConfiguration config, params IndexAttribute[] indexes) 
    { 
     return config.HasColumnAnnotation("Index", new IndexAnnotation(indexes)); 
    } 
} 

Und hier ist die neue Nutzung:

Property(x => x.Name).IsRequired().HasMaxLength(65).HasIndex(new IndexAttribute("IX_Countries_Name") { IsUnique = true }, new IndexAttribute("IX_Countries_Published", 2)) 

Antwort

25

Dies liegt daran, jede Ihrer Erweiterungsmethoden a zuweisen neue Anmerkung zu einer Eigenschaft und überschreibt die vorherige. Lassen Sie mich das zeigen, indem Sie Ihre Methoden in einem Beispiel verwenden.

Sagen wir diese (nutzlosen) Klasse

public class Client 
{ 
    public int ClientId { get; set; } 
    public int CompanyId { get; set; } 
    public int AddressId { get; set; } 
} 

Und Ihre Indexdefinitionen gelten (Überspringen der Teil modelBuilder.Entity<Client>()):

.Property(c => c.ClientId).HasIndex("ClientCompanyIndex"); 
.Property(c => c.CompanyId).HasIndex("ClientCompanyIndex", 2); 
.Property(c => c.ClientId).HasIndex("ClientAddressIndex"); 
.Property(c => c.AddressId).HasIndex("ClientAddressIndex", 2); 

die Erweiterungsmethoden Inlining (Gott sei Dank für ReSharper) Dies führt zu

.Property(c => c.ClientId).HasColumnAnnotation("Index", 
    new IndexAnnotation(new IndexAttribute("ClientCompanyIndex", 1)); 
.Property(c => c.CompanyId).HasColumnAnnotation("Index", 
    new IndexAnnotation(new IndexAttribute("ClientCompanyIndex", 2)); 
.Property(c => c.ClientId).HasColumnAnnotation("Index", 
    new IndexAnnotation(new IndexAttribute("ClientAddressIndex", 1)); 
.Property(c => c.AddressId).HasColumnAnnotation("Index", 
    new IndexAnnotation(new IndexAttribute("ClientAddressIndex", 2)); 

Dies ist das gleiche wie Schreiben

[Index("ClientCompanyIndex", Order = 1)] 
public int ClientId { get; set; } 

und dann es von

[Index("ClientAddressIndex", Order = 1)] 
public int ClientId { get; set; } 

ersetzt die richtige Anmerkung zu reproduzieren ...

[Index("ClientAddressIndex", IsUnique = true, Order = 1)] 
[Index("ClientCompanyIndex", IsUnique = true, Order = 1)] 
public int ClientId { get; set; } 
[Index("ClientCompanyIndex", IsUnique = true, Order = 2)] 
public int CompanyId { get; set; } 
[Index("ClientAddressIndex", IsUnique = true, Order = 2)] 
public int AddressId { get; set; } 

... die Konfiguration der ClientId Eigenschaft wie

aussehen sollte
.Property(c => c.ClientId).HasColumnAnnotation("Index", 
    new IndexAnnotation(new[] 
     { 
      new IndexAttribute("ClientCompanyIndex", 1), 
      new IndexAttribute("ClientAddressIndex", 1) 
     })); 

Jetzt ist es plötzlich weniger attraktiv, Erweiterungsmethoden zu erstellen. Es lohnt sich kaum, einen für diese kombinierte Anmerkung zu erstellen. Aber für Einwegspalten sind Ihre Methoden eine Verbesserung.

Natürlich ist es klar, warum Sie das versuchen. Die aktuelle fließende Syntax ist klobig, um es gelinde auszudrücken. Das EF-Team knows this perfectly well und sie hoffen auf einige Mitwirkende, um dieses Problem bald zu greifen. Vielleicht etwas für dich?

+0

Danke Gert. Ich dachte mir, dass das vielleicht passieren könnte. Das letzte Beispiel zeigt mir, was ich als nächstes machen muss.Ich werde wahrscheinlich meine Hilfsklasse anpassen, um 'params IndexAttribute [] indexes 'zu akzeptieren, so dass ich mehrere Indizes pro Eigenschaft übergeben kann. Neuer Code zur Frage hinzugefügt. – Sam

+0

+1. In Ihrem letzten Beispielcode haben Sie das 'IsUnique' Attribut verpasst, es sollte' neues IndexAttribute ("ClientCompanyIndex", 1) {IsUnique = true} 'und' neues IndexAttribute ("ClientAddressIndex", 1) {IsUnique = sein wahr} '. –

Verwandte Themen