Как связать одну таблицу со многими родителями с помощью EF Code First

Я создаю модель предметной области, которая требует, чтобы несколько таблиц могли быть ссылками более чем на одну возможную родительскую таблицу. Например, у вас может быть таблица для хранения заметок или файлов, и эти заметки и/или файлы могут быть связаны с разными родительскими объектами. Дело не в том, что один и тот же «файл» или «заметка» могут быть связаны с несколькими владельцами, а в том, что из 10 строк в таблице «файлы» 3 из них могут принадлежать строкам из таблицы «Клиент», 3 из них могут быть принадлежат строкам из таблицы «Заказы», ​​а 4 из них могут принадлежать строкам из таблицы «Лица».

Все таблицы-владельцы имеют виртуальные ICollections дочерних таблиц.

Когда я прогнал свою модель через первую миграцию кода для начальной миграции и посмотрел на сгенерированный свободный код, определение таблицы для этих таблиц включало несколько столбцов идентификаторов, которые ссылались на исходную таблицу, так что должен был быть столбец «customer_id », «person_id» и т. д. (по одному для каждой возможной «сущности-владельца». Это кажется не совсем «правильным». Есть ли лучший способ смоделировать это в EF с помощью CodeFirst? Например, возможность использовать столбец дискриминатора в дочерняя таблица, которая дает «подсказку» о владеющем объекте?

Спасибо, - г-н Б.


person Matthew Belk    schedule 18.10.2012    source источник


Ответы (2)


Если вы создадите отношение «многие ко многим» между заметками и всеми объектами, которые могут иметь заметки, у вас будет соединительная таблица для каждого типа владения и красивая и чистая таблица заметок. Самый простой способ создать отношения «многие ко многим» — переопределить метод DbContext.OnModelCreating.

Ваш DbContext:

  public class MyDatabase : DbContext
  {
    // Protected methods

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
      base.OnModelCreating(modelBuilder);

      modelBuilder.Entity<Customer>().HasMany(x => x.Notes).WithMany();
      modelBuilder.Entity<Order>().HasMany(x => x.Notes).WithMany();
    }

    public MyDatabase() : base("MyDatabase")
    {
    }

    // Properties

    public DbSet<Customer> Customers { get; set; }

    public DbSet<Order> Orders { get; set; }

    public DbSet<Note> Notes { get; set; }
  }

В результате будут созданы следующие таблицы: Клиент, Заказы, Примечания, Примечания клиентов и Примечания к заказам причем последние две таблицы являются соединительными таблицами, каждая из которых содержит только два столбца.

ПРИМЕЧАНИЕ! С помощью этого решения организации также могут обмениваться заметками, например. Клиент и Заказ могут владеть одной и той же Нотой.

person Daniel Persson    schedule 20.10.2012

Не уверен, что подходит, но вы можете использовать иерархии EF для этого. См. эту статью:

http://weblogs.asp.net/manavi/archive/2010/12/24/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-1-table-per-hierarchy-tph.aspx

По сути, у вас может быть три типа заметок, унаследованных от базового типа заметок.

В EF есть три типа иерархий, поэтому это статья из трех частей...

person jjslagace    schedule 20.10.2012