Utilizzando tipi complessi, la convenzione di denominazione delle colonne predefinita utilizza il carattere di sottolineatura. Ciò significa che il tipo è definito in questo modo:
[ColmplexType]
public class Contact
{
string Email {get;set;}
string Post {get;set;}
}
public EntityN
{
//...
public Contact Contact {get;set;}
}
otterremo colonne denominate in questo modo
Contact_Email nvarchar(max)
Contact_Post nvarchar(max)
Naturalmente potremmo configurare separatamente ogni nome di colonna usando il mapping ColumnAttribute o Context.Properties, ma abbiamo la possibilità di creare una convenzione di denominazione e quindi configurare tutti i nomi in una volta per il tipo di currnet?
Per alcuni tipi complessi preferirei non menzionare affatto il nome della proprietà ("Contatto") per gli altri utenti, per connettere il nome e l'attributo utilizzando CammelCase, e mai utilizzare il carattere di sottolineatura.
Discussione:
Funziona (crea informazioni di configurazione per una tabella specifica)
public class CustomComplexTypeAttributeConvention : ComplexTypeAttributeConvention
{
public override void Apply(ConventionTypeConfiguration configuration, ComplexTypeAttribute attribute)
{
Properties().Where(pi => pi.DeclaringType == typeof(Contact))
.Configure(p => p.HasColumnName(p.ClrPropertyInfo.Name)
);
base.Apply(configuration, attribute);
}
}
e OnModelCreating
modelBuilder.Conventions.AddBefore<ComplexTypeAttributeConvention>(new CustomComplexTypeAttributeConvention());
Funziona, ma non sono sicuro che sia un metodo corretto per la codifica: 1) il "AddBefore" funziona come previsto (non voglio eliminare il comportamento predefinito, voglio solo sovrascrivere il comportamento predefinito per un caso)? 2) dove è l'opzione migliore per mettere "codice personalizzato" per applicare il metodo o al costruttore.
Il punto di rottura e il disassemblaggio di ComplexTypeAttributeConvention danno l'idea che non ignoriamo la convenzione di denominazione "predefinita", ma utilizziamo il "ciclo" attraverso "tutti gli attributi di tutti i tipi".
Sembra la soluzione più solida, ma è ancora un "hack" (non sovrascrive la convenzione di "sottolineatura" predefinita, ma emula i regali di "ColumnAttribute"):
public class BriefNameForComplexTypeConvention<T> : Convention
{
public BriefNameForComplexTypeConvention()
{
Properties().Where(pi => pi.DeclaringType == typeof(T))
.Configure(p => p.HasColumnName(p.ClrPropertyInfo.Name)
);
}
}
// ...
modelBuilder.Conventions.Add(new BriefNameForComplexTypeConvention<Contact>());
Non l'ho mai fatto prima, ma vale la pena provare ComplexTypeAttributeConvention
, puoi rimuovere quello predefinito e aggiungere quello personalizzato a DbModelBuilder.Conventions
:
public class CustomComplexTypeAttributeConvention : ComplexTypeAttributeConvention {
public CustomComplexTypeAttributeConvention(){
Properties().Configure(p => p.HasColumnName(p.ClrPropertyInfo.Name));
}
}
protected override void OnModelCreating(DbModelBuilder modelBuilder){
modelBuilder.Conventions.Remove<ComplexTypeAttributeConvention>();
modelBuilder.Conventions.Add(new CustomComplexTypeAttributeConvention());
//...
}