Sono in procinto di creare un modello di dominio e vorrei avere una classe "BaseEntity" con una proprietà "Id" (e qualche altra roba di tracciamento del controllo). La proprietà Id è la chiave primaria e ogni Entità nel mio modello di dominio erediterà dalla classe BaseEntity. Roba abbastanza semplice .....
public class BaseEntity
{
[Key]
public int Id { get; set; }
public DateTime LastUpdate { get; set; }
public string LastUpdateBy { get; set; }
}
public class Location : BaseEntity
{
[Required]
public string Name { get; set; }
public string Description { get; set; }
}
Utilizzando l'esempio sopra, vorrei mappare il campo "Id" a una colonna "LocationId". Capisco che posso usare il ModelBuilder per fare questo esplicitamente per ogni entità facendo qualcosa del genere:
modelBuilder.Entity<Location>().Property(s => s.Id).HasColumnName("LocationId");
Ma mi piacerebbe farlo per ogni Entity nel mio modello di dominio e sarebbe brutto.
Ho provato il seguente riflesso ma non ho avuto fortuna. Per qualsiasi motivo, il compilatore "non può risolvere il tipo di simbolo":
foreach (var type in GetTypesInNamespace(Assembly.Load("Domain.Model"),"Domain.Model"))
{
modelBuilder.Entity<type>().Property(x=>x.Id).....
}
C'è un modo per definire una convenzione per sovrascrivere la convenzione PrimaryKey predefinita per mappare la mia proprietà "Id" a una proprietà "ClassNameId" nel database? Sto usando Entity Framework 6.
Dovresti dare un'occhiata alle prime convenzioni del codice personalizzato . Hai bisogno di EF6 perché funzioni, ma sembra che tu lo stia già usando.
Solo per darti una panoramica, dai un'occhiata alla seguente convenzione che ho usato per convertire i nomi PascalCase in nomi di sottolineatura. Include una convenzione per le proprietà dell'ID ... Include anche un prefisso del nome della tabella opzionale.
public class UnderscoreNamingConvention : IConfigurationConvention<PropertyInfo, PrimitivePropertyConfiguration>,
IConfigurationConvention<Type, ModelConfiguration>
{
public UnderscoreNamingConvention()
{
IdFieldName = "Id";
}
public string TableNamePrefix { get; set; }
public string IdFieldName { get; set; }
public void Apply(PropertyInfo propertyInfo, Func<PrimitivePropertyConfiguration> configuration)
{
var columnName = propertyInfo.Name;
if (propertyInfo.Name == IdFieldName)
columnName = propertyInfo.ReflectedType.Name + IdFieldName;
configuration().ColumnName = ToUnderscore(columnName);
}
public void Apply(Type type, Func<ModelConfiguration> configuration)
{
var entityTypeConfiguration = configuration().Entity(type);
if (entityTypeConfiguration.IsTableNameConfigured) return;
var tableName = ToUnderscore(type.Name);
if (!string.IsNullOrEmpty(TableNamePrefix))
{
tableName = string.Format("{0}_{1}", TableNamePrefix, tableName);
}
entityTypeConfiguration.ToTable(tableName);
}
public static string ToUnderscore(string value)
{
return Regex.Replace(value, "(\\B[A-Z])", "_$1").ToLowerInvariant();
}
}
Lo usi in questo modo
modelBuilder.Conventions.Add(new UnderscoreNamingConvention { TableNamePrefix = "app" });
EDIT : Nel tuo caso, il metodo Apply
dovrebbe essere qualcosa del genere:
public void Apply(PropertyInfo propertyInfo, Func<PrimitivePropertyConfiguration> configuration)
{
if (propertyInfo.Name == "Id")
{
configuration().ColumnName = propertyInfo.ReflectedType.Name + "Id";
}
}
Provalo nella tua classe DbContext;
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Properties<int>()
.Where(p => p.Name.Equals("Id"))
.Configure(c => c.HasColumnName(c.ClrPropertyInfo.ReflectedType.Name + "Id"));
}
int è il tipo CLR dei miei campi Chiave primaria. Voglio fare riferimento a tutte le chiavi nel codice come Id, ma le DBA richiedono che le chiavi siano Id con il prefisso del nome dell'entità Tabella. Sopra mi dà esattamente quello che voglio nel mio database creato.
Entity Framework 6.x è richiesto.