2013-09-28 6 views
5

Come posso cambiare la convenzione di denominazione della tabella molti-a-molti generata automaticamente?Come modificare la convenzione di denominazione delle relazioni tabella Many-to-Many?

Si supponga che ho due classi:

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

Per impostazione predefinita, questo creerà una tabella chiamata UserRoles.

posso cambiare il nome della tabella uno a UsersInRoles, ad esempio, utilizzando il seguente nella esclusione OnModelCreating della mia DbContext:

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

Tuttavia, ciò che voglio veramente fare è modificare la convenzione di denominazione in modo tale che, per impostazione predefinita, tutte le tabelle molti-a-molti generate automaticamente utilizzino questa nuova convenzione. Non riesco a capire come farlo, o se è anche possibile. Non mi piace dover specificare 9 righe di codice extra ogni volta che si specifica una di queste relazioni.

Attualmente sto usando la versione EF 6.0.0-rc1.

+0

Per curiosità, perché vuoi davvero farlo? La codifica per convenzione perde tutto il suo fascino quando continui ad averne di differenti. –

+0

Si potrebbe dare un'occhiata a [Convenzioni personalizzate] (http://msdn.microsoft.com/en-us/data/jj819164.aspx). –

+0

@TonyHopkinson, Nel mio scenario reale, sto scrivendo un framework che cambia tutti i nomi delle tabelle con un prefisso basato sulla loro posizione "componente" (come Core, Risorse umane, Finanza, ecc.). Mentre ero in grado di scrivere un catch-all per la rinomina standard delle tabelle, non funzionava con queste tabelle many-to-many, e non riesco a capire come. Per quanto riguarda il mio esempio, ho usato questa convenzione per molto tempo e mi piacerebbe seguirlo. –

risposta

5

La possibilità di controllare le relazioni è stata rimossa dall'API delle convenzioni di base prima del rilascio perché non era in uno stato utilizzabile. È possibile accedere a tutte le proprietà e le tabelle nel modello tramite convenzioni basate su modelli. Una panoramica di convenzioni tipo based è disponibile qui: http://msdn.microsoft.com/en-US/data/dn469439

Questa soluzione comporta un po 'più scavare intorno nella API metadati, EntitySet è il tipo corretto per questo scenario

Questa convenzione dovrebbe rinominare la tabella rapporto generato:

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

Ne ho giocato un po ', ma ho scoperto che la convenzione EntityType non mi permette di rinominare le tabelle. La proprietà Set Name è interna. Quindi, di nuovo, sono bloccato a dover rinominare ogni tabella manualmente. –

+0

La convenzione sopra risolve il tuo problema o c'è qualcos'altro di cui hai bisogno? – lukew

+0

No, è perfetto! Non posso dire di avere quasi la stessa familiarità con la parte EDM, ma sta funzionando alla grande. Grazie! –