Entity Framework
Escenarios de mapeo avanzados: división de entidades, división de tablas
Buscar..
Introducción
Cómo configurar su modelo EF para admitir la división de entidades o la división de tablas.
División de la entidad
Digamos que tienes una clase de entidad como esta:
public class Person
{
public int PersonId { get; set; }
public string Name { get; set; }
public string ZipCode { get; set; }
public string City { get; set; }
public string AddressLine { get; set; }
}
Y luego digamos que desea asignar esta entidad de Persona a dos tablas: una con el PersonId y el Nombre, y otra con los detalles de la dirección. Por supuesto, también necesitaría el PersonId aquí para identificar a qué persona pertenece la dirección. Básicamente, lo que quieres es dividir la entidad en dos (o incluso más) partes. De ahí el nombre, división de entidades. Puede hacer esto asignando cada una de las propiedades a una tabla diferente:
public class MyDemoContext : DbContext
{
public DbSet<Person> Products { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Person>().Map(m =>
{
m.Properties(t => new { t.PersonId, t.Name });
m.ToTable("People");
}).Map(m =>
{
m.Properties(t => new { t.PersonId, t.AddressLine, t.City, t.ZipCode });
m.ToTable("PersonDetails");
});
}
}
Esto creará dos tablas: People y PersonDetails. La persona tiene dos campos, PersonId y Name, PersonDetails tiene cuatro columnas, PersonId, AddressLine, City y ZipCode. En Personas, PersonId es la clave principal. En PersonDetails, la clave principal también es PersonId, pero también es una clave externa que hace referencia a PersonId en la tabla Person.
Si consulta el DbSet de personas, EF realizará una unión en los PersonIds para obtener los datos de ambas tablas para completar las entidades.
También puedes cambiar el nombre de las columnas:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Person>().Map(m =>
{
m.Properties(t => new { t.PersonId });
m.Property(t => t.Name).HasColumnName("PersonName");
m.ToTable("People");
}).Map(m =>
{
m.Property(t => t.PersonId).HasColumnName("ProprietorId");
m.Properties(t => new { t.AddressLine, t.City, t.ZipCode });
m.ToTable("PersonDetails");
});
}
Esto creará la misma estructura de tabla, pero en la tabla Personas habrá una columna PersonName en lugar de la columna Nombre, y en la tabla PersonDetails habrá un ProprietorId en lugar de la columna PersonId.
División de la mesa
Y ahora digamos que desea hacer lo contrario a la división de entidades: en lugar de asignar una entidad a dos tablas, le gustaría asignar una tabla a dos entidades. Esto se llama división de tabla. Digamos que tienes una tabla con cinco columnas: PersonId, Name, AddressLine, City, ZipCode, donde PersonId es la clave principal. Y luego te gustaría crear un modelo EF como este:
public class Person
{
public int PersonId { get; set; }
public string Name { get; set; }
public Address Address { get; set; }
}
public class Address
{
public string ZipCode { get; set; }
public string City { get; set; }
public string AddressLine { get; set; }
public int PersonId { get; set; }
public Person Person { get; set; }
}
Una cosa salta de inmediato: no hay AddressId en la dirección. Esto se debe a que las dos entidades se asignan a la misma tabla, por lo que también deben tener la misma clave principal. Si haces la división de tablas, esto es algo con lo que tienes que lidiar. Entonces, además de la división de tablas, también debe configurar la entidad de Dirección y especificar la clave primaria. Y aquí está cómo:
public class MyDemoContext : DbContext
{
public DbSet<Person> Products { get; set; }
public DbSet<Address> Addresses { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Address>().HasKey(t => t.PersonId);
modelBuilder.Entity<Person>().HasRequired(t => t.Address)
.WithRequiredPrincipal(t => t.Person);
modelBuilder.Entity<Person>().Map(m => m.ToTable("People"));
modelBuilder.Entity<Address>().Map(m => m.ToTable("People"));
}
}