entity framework - usar - Herencia de tabla por tipo con EF 4.1 Código fluido primero
entity framework ventajas y desventajas (2)
¿Has leído el siguiente artículo?
Es un artículo de 3 partes que cubre los siguientes enfoques
Tabla por jerarquía (TPH): habilite el polimorfismo desnormalizando el esquema de SQL y utilice una columna de discriminación de tipo que contenga información de tipo.
Tabla por tipo (TPT): representa las relaciones "is a" (herencia) como "tiene una" (clave externa).
Tabla por clase concreta (TPC): descarte completamente las relaciones de herencia y polimorfismo del esquema de SQL.
Tengo un conjunto bastante directo de tablas de bases de datos, como:
Vehicle
Id
RegNo
Car
Id (FK of Vehicle.Id)
OtherStuff
Bike
Id (FK of Vehicle.Id)
MoreStuff
Mi modelo de clase es como era de esperar: con Vehicle siendo una clase abstracta, y luego Car y Bike siendo subclases de ella.
Configuré mi configuración EF4.1 Code First de la siguiente manera:
class VehicleConfiguration : EntityTypeConfiguration<Vehicle> {
public VehicleConfiguration() {
ToTable("Vehicles");
Property(x => x.Id);
Property(x => x.RegNo);
HasKey(x => x.Id);
}
}
class CarConfiguration : EntityTypeConfiguration<Car> {
public CarConfiguration() {
ToTable("Cars");
Property(x => x.OtherStuff);
}
}
class BikeConfiguration : EntityTypeConfiguration<Bike> {
public BikeConfiguration() {
ToTable("Bikes");
Property(x => x.MoreStuff);
}
}
Sin embargo, recibo numerosas excepciones extrañas cuando EF intentó construir su configuración de modelo.
Actualmente está tirando esto:
System.Data.EntityCommandExecutionException: An error occurred while executing the command definition. See the inner exception for details. ---> System.Data.SqlClient.SqlException: Invalid column name ''Discriminator''.
¿De dónde está obteniendo ese nombre de columna? No está en ninguno de mis códigos o en la base de datos en sí. Debe ser alguna convención que se haga cargo del control. ¿Cómo le indico a EF que use table-per-type?
Si elimino la palabra clave "abstracta" de mi clase Vehículo (lo cual hice como una prueba de cordura en algún punto de la línea), entonces recibo una excepción diferente como la siguiente:
(35,10) : error 3032: Problem in mapping fragments starting at lines 30, 35:EntityTypes AcmeCorp.Car, AcmeCorp.Bike are being mapped to the same rows in table Vehicles. Mapping conditions can be used to distinguish the rows that these types are mapped to.
Obviamente estoy haciendo algo terriblemente mal, pero ¿qué? ¡He seguido los documentos de MSDN y todos los demás artículos de TPT + EF4.1 que puedo encontrar!
Cuando tuve este problema, descubrí que tenía una subclase que no estaba mapeada. En este ejemplo, algunas causas posibles de esto son:
- Existe una subclase adicional, como
Bus
. Esto no está mapeado. - Una de las subclases, como
Car
, no está asignada.
En este caso, asegúrese de que cada subclase esté mapeada:
- Asegúrese de que exista una asignación para la subclase, incluida una
ToTable
métodoToTable
. - Asegúrese de que la asignación se esté aplicando realmente durante
OnModelCreating
. - Si tiene problemas para rastrear esto, intente usar un depurador y establecer puntos de interrupción en todo el código de mapeo.
De forma alternativa, si la subclase no debe asignarse en primer lugar, asegúrese de que se ignore utilizando una de las llamadas al método Ignore
.