Szukaj…


Wprowadzenie

Jak skonfigurować model EF, aby obsługiwał podział encji lub podział tabeli.

Podział jednostek

Powiedzmy, że masz klasę encji taką:

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; }
}

Powiedzmy, że chcesz zmapować ten byt Person na dwie tabele - jedną z PersonId i Nazwą, a drugą ze szczegółami adresu. Oczywiście potrzebujesz tutaj również PersonId, aby określić, do której osoby należy adres. Więc w zasadzie chcesz podzielić byt na dwie (lub nawet więcej) części. Stąd nazwa, podział bytu. Możesz to zrobić, mapując każdą z właściwości do innej tabeli:

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");
      });
  }
}

Spowoduje to utworzenie dwóch tabel: People i PersonDetails. Osoba ma dwa pola: PersonId i Imię, PersonDetails ma cztery kolumny, PersonId, AddressLine, City i ZipCode. W People, PersonId jest kluczem podstawowym. W PersonDetails kluczem podstawowym jest również PersonId, ale jest to również klucz obcy odwołujący się do PersonId w tabeli Person.

Jeśli zapytasz People DbSet, EF wykona łączenie na PersonIds, aby uzyskać dane z obu tabel w celu zapełnienia jednostek.

Możesz także zmienić nazwę kolumn:

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");
  });
}

Spowoduje to utworzenie tej samej struktury tabeli, ale w tabeli Osoby będzie kolumna PersonName zamiast kolumny Nazwa, aw tabeli PersonDetails będzie kolumna ProprietorId zamiast kolumny PersonId.

Podział stołu

A teraz powiedzmy, że chcesz zrobić coś przeciwnego do podziału encji: zamiast mapować jedną encję na dwie tabele, chciałbyś mapować jedną tabelę na dwie encje. Nazywa się to dzieleniem tabel. Załóżmy, że masz jedną tabelę z pięcioma kolumnami: PersonId, Name, AddressLine, City, ZipCode, gdzie PersonId jest kluczem podstawowym. A następnie chciałbyś stworzyć taki model EF:

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; }
}

Jedna rzecz wyskakuje natychmiast: w adresie nie ma adresu. Jest tak, ponieważ dwa podmioty są odwzorowane na tę samą tabelę, więc muszą mieć również ten sam klucz podstawowy. Jeśli dzielisz stoliki, musisz sobie z tym poradzić. Tak więc oprócz podziału tabeli musisz także skonfigurować encję Adres i określić klucz podstawowy. A oto jak:

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"));
  }
}


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow