Entity Framework
Geavanceerde mapping-scenario's: entiteitsplitsing, tabelsplitsing
Zoeken…
Invoering
Hoe u uw EF-model kunt configureren om het splitsen van entiteiten of het splitsen van tabellen te ondersteunen.
Entiteit splitsen
Laten we zeggen dat u een entiteitsklasse als deze hebt:
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; }
}
En laten we vervolgens zeggen dat u deze entiteit Persoon in twee tabellen wilt toewijzen - een met de PersonId en de naam, en een andere met de adresgegevens. Natuurlijk zou u hier ook de PersonId nodig hebben om te identificeren tot welke persoon het adres behoort. Dus eigenlijk wilt u de entiteit in twee (of zelfs meer) delen splitsen. Vandaar de naam, entiteit splitsen. U kunt dit doen door elk van de eigenschappen toe te wijzen aan een andere tabel:
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");
});
}
}
Hiermee worden twee tabellen gemaakt: People en PersonDetails. Persoon heeft twee velden, PersonId en Naam, PersonDetails heeft vier kolommen, PersonId, AddressLine, City en ZipCode. In People is PersonId de primaire sleutel. In PersonDetails is de primaire sleutel ook PersonId, maar het is ook een externe sleutel die verwijst naar PersonId in de Personentabel.
Als u de People DbSet opvraagt, doet EF een join op de PersonIds om de gegevens uit beide tabellen op te halen om de entiteiten te vullen.
U kunt ook de naam van de kolommen wijzigen:
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");
});
}
Hiermee wordt dezelfde tabelstructuur gemaakt, maar in de tabel Personen is er een kolom PersonName in plaats van de kolom Name en in de tabel PersonDetails staat er een ProprietorId in plaats van de PersonId-kolom.
Tafelsplitsing
En laten we nu zeggen dat u het tegenovergestelde wilt doen van het splitsen van entiteiten: in plaats van één entiteit in twee tabellen toe te wijzen, wilt u één tabel in twee entiteiten toewijzen. Dit wordt tabelsplitsing genoemd. Stel dat u één tabel met vijf kolommen hebt: PersonId, Name, AddressLine, City, ZipCode, waarbij PersonId de primaire sleutel is. En dan wilt u een EF-model als dit maken:
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; }
}
Eén ding springt er meteen uit: er is geen AddressId in Address. Dat komt omdat de twee entiteiten aan dezelfde tabel zijn toegewezen, dus moeten ze ook dezelfde primaire sleutel hebben. Als je tafelsplitsing doet, is dit iets waar je gewoon mee te maken hebt. Dus naast het splitsen van tabellen, moet u ook de entiteit Adres configureren en de primaire sleutel opgeven. En hier is hoe:
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"));
}
}