En el post anterior vimos el tipo de herencia Table per Hierarchy (TPH).
Ahora vamos a ver el tipo de herencia en que el tipo base se guarda en una tabla compartida, es lo que llamamos Table per Type (TPT).
En el ejemplo que estamos siguiendo (intro), nuestra clase base Product se guardará en la tabla ProductsTpT que tiene las propiedades de la propia clase base y luego tendremos una tabla por cada subtipo: ShirtsTpT, BooksTpT y TelevisionsTpT como podemos ver a continuación:
Ahora vamos a definir los mapeos de la base de datos con nuestras clases.
Para la clase base Product:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class ProductsTpTConfiguration : EntityConfiguration<Product>
{
public ProductsTpTConfiguration()
{
this
.HasKey(p => p.Id)
.MapHierarchy(
p => new
{
ProductId = p.Id,
ProductName = p.Name,
ProductPrice = p.Price
}
)
.ToTable("ProductsTpT");
}
}
Para los subtipos:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
public class BooksTpTConfiguration : EntityConfiguration<Book>
{
public BooksTpTConfiguration()
{
this
.MapHierarchy(
b => new
{
Id = b.Id,
Pages = b.PageNumber,
Author = b.Author
}
)
.ToTable("BooksTpT");
}
}
public class TelevisionsTpTConfiguration : EntityConfiguration<Television>
{
public TelevisionsTpTConfiguration()
{
this
.MapHierarchy(
t => new
{
Id = t.Id,
Size = t.Size,
Brand = t.Brand
}
)
.ToTable("TelevisionsTpT");
}
}
public class ShirtsTpTConfiguration : EntityConfiguration<Shirt>
{
public ShirtsTpTConfiguration()
{
this
.MapHierarchy(
s => new
{
Id = s.Id,
Colour = s.Colour,
Size = s.Size
}
)
.ToTable("ShirtsTpT");
}
}
Como podemos observar, en cada expresión MapHierarchy solo mapeamos las propiedades declaradas por el propio tipo, y las que se refieran a su clave primaria.
Para crear las instancias a las que añadimos nuestros objetos utilizaremos una clase que herede de ObjectContext. Podeis observar que es la misma que la del ejemplo de Table per Hierarchy:
1
2
3
4
5
6
7
8
9
10
11
12
13
publicclassModelContext : ObjectContext
{
publicModelContext(EntityConnection connection)
: base(connection)
{
DefaultContainerName = "ModelContext";
}
public IObjectSet<Product> Products
{
get { returnbase.CreateObjectSet<Product>(); }
}
}
Y finalmente, para terminar nuestro ejemplo y persistir los 3 tipos a las diferentes tablas lo haremos de la siguiente forma:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
publicvoidAddProducts()
{
// crear la conexión a la BBDD y crear el contexto de EF
SqlConnection conn = new SqlConnection("Data Source=(local);Initial Catalog=Serrate.CodeOnly;Integrated Security=True;MultipleActiveResultSets=True;");
var builder = new ContextBuilder<ModelContext>();
// debemos añadir las 4 configuraciones que equivalen a cada tabla