2014-06-21 21 views
15

Wygląda na to, że w Entity Framework 6.1 dodano możliwość tworzenia indeksów tabel za pomocą nowej metody HasColumnAnnotation. Stworzyłem kilka rozszerzeń pomocnika, aby przyspieszyć proces:Wiele indeksów możliwe przy użyciu 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 })); 
    } 
} 

Działa to fantastyczne ... aż próbuję utworzyć drugi indeks, który zawiera kolumnę już używany w innym indeksem. Wszystko, co dodaję, powoduje nadpisanie oryginału. Czy ktoś wie, czy obecnie możliwe jest dodawanie wielu indeksów do tej samej kolumny za pośrednictwem nowego HasColumnAnnotation dostępnego na StringPropertyConfiguration i PrimitivePropertyConfiguration?

Mogę to obejść tak, jak zawsze, ręcznie dodając indeksy w skryptach migracji, ale najlepiej byłoby móc skonfigurować to w mapowaniach EntityTypeConfiguration, więc mogę mieć wszystko w jednym miejscu.


Po Gerts sprzężenia zwrotnego, to jest to, co skończyło się robi:

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

A oto nowy zwyczaj:

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

Odpowiedz

25

To dlatego, że każdy z twoich metod rozszerzenie przypisać nową adnotację do właściwości i zastąpić poprzednią. Pozwól, że pokażę to, używając twoich metod w przykładzie.

że mamy to (bezużyteczny) Klasa

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

i zastosować definicji indeksu (z pominięciem części 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); 

inline metod przedłużających (dzięki Bogu za Resharper) prowadzi to

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

To jest to samo, co pisanie

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

a następnie zastępując go

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

Do odtworzenia prawidłowej adnotacji ...

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

... konfiguracja własności ClientId powinien wyglądać

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

Teraz nagle tworzenie metod rozszerzeń jest znacznie mniej atrakcyjne. Nie jest to warte wysiłku, aby stworzyć taką połączoną adnotację. Ale w przypadku kolumn jednorazowych twoje metody stanowią ulepszenie.

Oczywiście jasne jest, dlaczego próbujesz tego. Obecna płynna składnia jest co najmniej dziwna. Zespół EF nr knows this perfectly well ma nadzieję, że jakiś uczestnik wkrótce przejdzie ten problem. Może coś dla ciebie?

+0

Dziękuję Gert. Pomyślałem, że to może być to, co się dzieje. Ostatni przykład pokazuje mi, co muszę zrobić dalej.Prawdopodobnie dostosuję moją klasę pomocniczą, aby zaakceptować 'parametry IndexAttribute [] index', dzięki czemu mogę przekazywać wiele indeksów dla każdej właściwości. Nowy kod dodany do pytania. – Sam

+0

+1. W twoim ostatnim fragmencie przykładowego kodu przegapiłeś atrybut 'IsUnique', powinien to być' nowy IndexAttribute ("ClientCompanyIndex", 1) {IsUnique = true} 'i' new IndexAttribute ("ClientAddressIndex", 1) {IsUnique = true} '. –

Powiązane problemy