Pregunta

Estoy utilizando el código de Entity Framework 4 CTP5 primer acercamiento y tengo una tabla por jerarquía de mapeo (TPH). Algunos de mis clases en la jerarquía tienen propiedades en común.

public class BaseType
{
    public int Id { get; set; }
}

public class A : BaseType
{
    public string Customer { get; set; }
    public string Order { get; set; }
}

public class B : BaseType
{
    public string Customer { get; set; }
    public string Article { get; set; }
}

public class C : BaseType
{
    public string Article { get; set; }
    public string Manufacturer { get; set; }
}

La convención default asigna esto a las siguientes columnas:

  • Id
  • Artículo 1
  • Article2
  • Customer1
  • Customer2
  • Fabricante
  • Solicitar
  • Tipo

Quiero tener EF4 cuota de las propiedades comunes a terminar con lo siguiente:

  • Id
  • artículo
  • cliente
  • Fabricante
  • Solicitar
  • Tipo

Además de la reducción del número de columnas, esto tiene la ventaja de ser capaz de buscar registros basados ??en el artículo, por ejemplo, sin tener que saber exactamente qué tipos tienen una propiedad del artículo.

He intentado mapear cada propiedad común a la misma columna:

modelBuilder.Entity<B>().Property(n => n.Article).HasColumnName("Article");
modelBuilder.Entity<C>().Property(n => n.Article).HasColumnName("Article");

pero esto arrojó la siguiente excepción:

esquema especificado no es válido. Errores: (36.6): Error 0019: Cada nombre de la propiedad en un tipo deben ser únicos. Nombre de la propiedad 'artículo' ya estaba definido.

¿Alguien sabe cómo moverse por esta regla de validación?

¿Fue útil?

Solución

No hay ninguna solución a la derivación de esta validación. En TPH una columna es o bien pertenece a la clase base que se hereda por todos los childs o está especializada a la clase de niño. No se puede instruir a EF para asignarlo a dos de sus niño, pero no para el otro. El intento de hacerlo (por ejemplo, poniendo en [Column(Name = "Customer")] tanto A.Customer y B.Customer) se causando un MetadataException con este mensaje:

esquema especificado no es válido. errores: (10,6): Error 0019: El nombre de cada propiedad en un tipo debe ser único. Nombre de la propiedad 'Cliente' ya estaba definido.


TPH Solución:

Una solución a este sería promover propiedades Customer y Article a la clase base:

public class BaseType {
    public int Id { get; set; }
    public string Customer { get; set; }
    public string Article { get; set; }
}

public class A : BaseType {
    public string Order { get; set; }
}

public class B : BaseType { }

public class C : BaseType {
    public string Manufacturer { get; set; }
}

¿Qué resultados en el esquema deseado:

text alt


Solución TPT (Recomendado):

Dicho esto, recomiendo considerar el uso de Mesa por tipo (TPT), ya que es un mejor ajuste para su escenario:

public class BaseType
{
    public int Id { get; set; }
}

public class A : BaseType
{
    [Column(Name = "Customer")]
    public string Customer { get; set; }
    public string Order { get; set; }
}

public class B : BaseType
{
    [Column(Name = "Customer")]
    public string Customer { get; set; }

    [Column(Name = "Article")]
    public string Article { get; set; }
}

public class C : BaseType
{
    [Column(Name="Article")]
    public string Article { get; set; }
    public string Manufacturer { get; set; }
}

public class MyContext : DbContext
{
    public DbSet<BaseType> BaseTypes { get; set; }        

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<BaseType>().ToTable("BaseType");
        modelBuilder.Entity<A>().ToTable("A");
        modelBuilder.Entity<C>().ToTable("C");
        modelBuilder.Entity<B>().ToTable("B");          
    }
}

text alt

Otros consejos

Para cualquier persona que estaba teniendo problemas con este tema, ahora se ha fijado en EF6: Entidad - CodePlex

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top