Поиск…


Вступление

Как настроить модель EF для поддержки разделения объектов или разбиения таблиц.

Разделение сущностей

Итак, допустим, у вас есть класс сущности:

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

И затем предположим, что вы хотите сопоставить объект Person в двух таблицах: один с PersonId и Name, а другой с данными адреса. Конечно, вам также понадобится PersonId, чтобы определить, к кому принадлежит адрес. Таким образом, в основном вы хотите разделить объект на две (или даже более) части. Следовательно, имя, сущность разбивается. Вы можете сделать это, сопоставляя каждое из свойств с другой таблицей:

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

Это создаст две таблицы: People и PersonDetails. У человека есть два поля: PersonId и Name, PersonDetails имеет четыре столбца: PersonId, AddressLine, City и ZipCode. В People PersonId является основным ключом. В PersonDetails основным ключом также является PersonId, но он также является внешним ключом, ссылающимся на PersonId в таблице Person.

Если вы запросите People DbSet, EF сделает соединение в PersonIds, чтобы получить данные из обеих таблиц, чтобы заполнить сущности.

Вы также можете изменить название столбцов:

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

Это создаст одну и ту же структуру таблицы, но в таблице «Люди» вместо столбца «Имя» будет столбец «Имя пользователя», а в таблице PersonDetails вместо столбца PersonId будет создан ProprietorId.

Разделение таблиц

А теперь предположим, что вы хотите сделать противоположное от разделения объектов: вместо сопоставления одного объекта в две таблицы вам нужно сопоставить одну таблицу с двумя объектами. Это называется разбиением таблиц. Допустим, у вас есть одна таблица с пятью столбцами: PersonId, Name, AddressLine, City, ZipCode, где PersonId является первичным ключом. И тогда вы хотели бы создать 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; }
}

Одна вещь выпрыгивает прямо: в Address Address отсутствует адрес. Это связано с тем, что два объекта отображаются в одну и ту же таблицу, поэтому они должны иметь одинаковый первичный ключ. Если вы разделите таблицу, это то, с чем вам просто нужно иметь дело. Поэтому, помимо разделения таблиц, вам также необходимо настроить объект Address и указать первичный ключ. И вот как:

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
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow