Entity Framework
Avancerade kartläggningsscenarier: enhetsdelning, tabelldelning
Sök…
Introduktion
Så konfigurerar du din EF-modell för att stödja enhetsdelning eller tabelldelning.
Enhetsdelning
Så låt oss säga att du har en enhetsklass som denna:
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; }
}
Och låt oss säga att du vill kartlägga denna Person-enhet i två tabeller - en med PersonId och Namnet, och en annan med adressinformationen. Naturligtvis skulle du behöva PersonId här också för att identifiera vilken person adressen tillhör. Så du vill i princip dela upp enheten i två (eller ännu fler) delar. Därför namnet, enhetens uppdelning. Du kan göra detta genom att kartlägga alla egenskaper till en annan tabell:
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");
});
}
}
Detta skapar två tabeller: People och PersonDetails. Person har två fält, PersonId och Namn, PersonDetails har fyra kolumner, PersonId, Adresslinje, Stad och ZipCode. I People är PersonId den primära nyckeln. I PersonDetails är den primära nyckeln också PersonId, men den är också en utländsk nyckel som refererar till PersonId i Person-tabellen.
Om du ifrågasätter People DbSet kommer EF att gå med i PersonIds för att få data från båda tabellerna för att fylla enheterna.
Du kan också ändra namnet på kolumnerna:
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");
});
}
Detta skapar samma tabellstruktur, men i People-tabellen finns en PersonName-kolumn istället för Name-kolumnen, och i PersonDetails-tabellen kommer det att finnas en ProprietorId istället för PersonId-kolumnen.
Bordsdelning
Och låt oss nu säga att du vill göra det motsatta av att dela upp en enhet: istället för att kartlägga en enhet i två tabeller, vill du kartlägga en tabell i två enheter. Detta kallas tabelldelning. Låt oss säga att du har en tabell med fem kolumner: PersonId, Name, AddressLine, City, ZipCode, där PersonId är den primära nyckeln. Och sedan skulle du vilja skapa en EF-modell som denna:
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; }
}
En sak hoppar rätt ut: det finns ingen AddressId i Address. Det beror på att de två enheterna är mappade till samma tabell, så de måste ha samma primära nyckel också. Om du gör tabelldelning är det något du bara måste ta itu med. Så förutom tabelldelning måste du också konfigurera adressenheten och ange den primära nyckeln. Och så här:
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"));
}
}