c# - mvc - Controlar el mapeo de columnas con una convención personalizada en Entity Framework 6
mvc crud entity framework (1)
Por lo que puedo ver, puede escribir la configuración de tipo en el método OnModelCreating
de su DbContext
y es muy similar al código que ya mencionó en la pregunta.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Types<TypeEntity>().Configure(c =>
{
c.HasKey(p => p.Key);
// probably not needed, but won''t do any harm
c.Property(p => p.Key).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
c.ToTable(c.ClrType.Name);
});
}
Si hay algún problema con este enfoque, házmelo saber y volveré a visitar el tema.
Editar:
El mismo principio exacto se puede aplicar con las convenciones:
class TypeEntityConvention : Convention
{
public TypeEntityConvention()
{
this.Types<TypeEntity>().Configure(c =>
{
c.HasKey(p => p.Key);
c.Property(p => p.Key).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
c.ToTable(c.ClrType.Name);
});
}
}
y
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Conventions.Add<TypeEntityConvention>();
}
Tengo una clase TypeEntity
que actuará como la clase base para varias docenas de entidades. Estoy usando TPC, por lo que necesito asignar todas las propiedades de la clase base a la tabla con el nombre de la clase concreta, y establecer el campo Key
para generar la base de datos.
Actualmente estoy haciendo esto con EntityTypeConfiguration
para cada tipo de entidad que se ve así:
class LineItemType : EntityTypeConfiguration<Models.LineItemType>
{
public LineItemType()
{
this.Property(e => e.Key)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
this.Map(e => e.MapInheritedProperties()
.ToTable(nameof(LineItemType)));
}
}
Esto funciona bien, pero es muy repetitivo. Tengo que recordar crear una clase de configuración para cada tipo que herede de TypeEntity
, establecer la clave y mapear las propiedades heredadas. Esto parece un caso ideal para una Convention
personalizada.
TypeEntityTpcConvention
una Convention
TypeEntityTpcConvention
siguiente manera:
class TypeEntityTpcConvention : Convention
{
public TypeEntityTpcConvention()
{
this.Types<TypeEntity>()
.Configure(e => e.Property(p => p.Key)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity));
}
}
Lo cual funciona para configurar Key
como base de datos generada, pero no puedo encontrar ninguna forma de acceder a las asignaciones de tabla para propiedades desde dentro de una convención.
Idealmente, esperaría algo como esto:
this.Types<TypeEntity>()
.Configure(e => e.MapInheritedProperties()
.ToTable(e.ClrType.Name));
O incluso una llamada como esta para cada propiedad que necesita ser mapeada:
this.Types<TypeEntity>()
.Configure(e => e.Property(p=>p.Key)
.ToTable(e.ClrType.Name));
Ninguno de los cuales parece existir. ¿Hay alguna manera de controlar el mapeo de propiedades desde dentro de una Convention
?
Después de algunas investigaciones adicionales, parece que hay opciones de convenciones más avanzadas disponibles como IStoreModelConvention
e IConceptualModelConvention
, pero la documentación útil sobre cómo usarlas es muy escasa. Después de varias horas hurgando en ellos con puntos de interrupción y viendo ventanas, tampoco he descubierto cómo controlar el mapeo de columnas usando estas interfaces.
Mi solución actual es usar la reflexión para encontrar todos los tipos que hereden de TypeEntity
en OnModelCreating
, y asignar las propiedades a la tabla correcta. Esto funciona, pero preferiría usar una convención si fuera posible, ya que esto realmente parece ser el tipo de cosa para la que se hicieron las convenciones. Siento que me falta algo obvio.