2013-09-28 5 views
5

Jak mogę zmienić konwencję nazewnictwa automatycznie generowanego tabeli wielu do wielu?Jak zmienić konwencję nazewnictwa relacji między wieloma a wieloma tabelami?

Przyjmijmy, mam dwie klasy:

public class User 
{ 
    public int UserId { get; set; } 
    public virtual List<Role> Roles { get; set; } 
} 

public class Role 
{ 
    public int RoleId { get; set; } 
    public virtual List<User> Users { get; set; } 
} 

domyślnie będzie to utworzyć tabelę o nazwie UserRoles.

mogę zmienić nazwę tego jeden tabeli UsersInRoles, na przykład, za pomocą następujących czynności w ręcznym OnModelCreating mojego DbContext:

modelBuilder.Entity<User>() 
    .HasMany(p => p.Roles) 
    .WithMany(p => p.Users) 
    .Map(mc => 
    { 
     mc.MapLeftKey("UserId"); 
     mc.MapRightKey("RoleId"); 
     mc.ToTable("UsersInRoles"); 
    }); 

Jednak to, co naprawdę chcesz robić zmienia konwencję nazewnictwa, tak aby domyślnie wszystkie automatycznie generowane tabele wielu do wielu używały tej nowej konwencji. Nie mogę wymyślić, jak to zrobić, lub jeśli to możliwe. Nie lubię określać 9 linii dodatkowego kodu za każdym razem, gdy określę jedną z tych relacji.

Obecnie używam wersji EF 6.0.0-rc1.

+0

Z ciekawości, dlaczego tak naprawdę chcesz to zrobić? Kodowanie według konwencji traci cały swój urok, gdy masz inne. –

+0

Możesz rzucić okiem na [Konwencje niestandardowe] (http://msdn.microsoft.com/en-us/data/jj819164.aspx). –

+0

@ TonyHopkinson, W moim prawdziwym scenariuszu piszę framework, który zmienia wszystkie nazwy tabel z prefiksem na podstawie ich "komponentowej" lokalizacji (takich jak Core, HR, Finanse, itp.). Chociaż udało mi się napisać catch-all dla standardowej zmiany nazwy tabeli, to nie działało z tymi tabelami "wiele do wielu", i nie potrafię zrozumieć, w jaki sposób. Jeśli chodzi o mój przykład, używam tej konwencji przez długi czas i chciałbym się z nią uporać. –

Odpowiedz

5

Możliwość sterowania relacjami została usunięta z interfejsu API podstawowych konwencji przed wydaniem, ponieważ nie była w stanie użytecznym. Możesz uzyskać dostęp do wszystkich właściwości i tabel w modelu poprzez konwencje oparte na modelu. Przegląd konwencji model oparty jest dostępny tutaj: http://msdn.microsoft.com/en-US/data/dn469439

Takie rozwiązanie wiąże się trochę więcej kopanie wokół w API metadanych, EntitySet jest odpowiedniego typu dla tego scenariusza

Ta konwencja powinna zmienić nazwę wygenerowanego tabeli relacji:

public class MyConvention : IStoreModelConvention<EntitySet> 
{ 
    public void Apply(EntitySet set, DbModel model) 
    { 
     var properties = set.ElementType.Properties; 
     if (properties.Count == 2) 
     { 
      var relationEnds = new List<string>(); 
      int i = 0; 
      foreach (var metadataProperty in properties) 
      { 
       if (metadataProperty.Name.EndsWith("_ID")) 
       { 
        var name = metadataProperty.Name; 
        relationEnds.Add(name.Substring(0, name.Length - 3)); 
        i++; 
       } 
      } 
      if (relationEnds.Count == 2) 
      { 
       set.Table = relationEnds.ElementAt(0) + "_" + relationEnds.ElementAt(1) + "_RelationTable"; 
      } 
     } 
    } 
+0

Odtwarzałem z tym trochę, ale odkryłem, że konwencja EntityType nie pozwala mi zmieniać nazw tabel. Właściwość Ustaw nazwę jest wewnętrzna. Więc znowu utknąłem z koniecznością ręcznej zmiany nazwy każdego stołu. –

+0

Czy powyższa konwencja rozwiązuje problem lub czy jest coś jeszcze, czego potrzebujesz? – lukew

+0

Nie, to jest idealne! Nie mogę powiedzieć, że jestem prawie tak samo zaznajomiony z częścią EDM, jak powinienem, ale działa to świetnie. Dzięki! –