2015-05-06 6 views
1

Я хочу создать отношения «многие ко многим», используя EF 6, используя подход, основанный на кодах. Мои объекты используют составной первичный ключ (для работы с несколькими арендаторами).EF множественное отношение внешнего ключа на том же первичном ключе

Давайте рассмотрим простой и классический пример. У меня есть две сущности Project и Person, которые имеют много-ко-многим:

public class Person 
{ 
    [Key, Column(Order = 1),] 
    public Int32 Id { get; set; } 
    [Key, Column(Order = 2)] 
    public int TenantId { get; set; } 
    public string Name { get; set; } 
} 

public class Project 
{ 
    [Key, Column(Order = 1),] 
    public Int32 Id { get; set; } 
    [Key, Column(Order = 2)] 
    public int TenantId { get; set; } 
    Public string Name { get; set; } 
} 

Я также имеют соединяющую таблицу ProjectPerson так:

Выше я определил Project к ProjectPerson отношения с. Обратите внимание, что открытый класс ProjectPerson { [Ключ, столбец (заказ = 1),] public Int32 Id {get; задавать; } [Ключ, колонка (заказ = 2)] [ForeignKey («Project»)] public int TenantId {get; задавать; }

[ForeignKey("Project")] 
    public int ProjectId { get; set; } 

    public DateTime AddedDate{ get; set; } 

    public virtual Project Project { get; set; } 
} 

TenantId Используется как часть основного и внешнего ключей.

До этого момента модель работает должным образом. Но отношения Person к ProjectPerson отсутствуют.

я добавил следующие две строки в ProjectPerson класса

[ForeignKey("Person")] 
    public int PersonId { get; set; } 

    public virtual Person Person { get; set; } 

Определенно, отображающей в TenantId отсутствует. Я не знаю, как определить его

Update

я нашел это. но все же им не удовлетворено, поскольку в качестве внешнего ключа есть дополнительный TenantId (PersonTenantId).

public class ProjectPerson 
{ 
    [Key, Column(Order = 1),] 
    public Int32 Id { get; set; } 
    [Key, Column(Order = 2)] 
    [ForeignKey("Project")] 
    public int TenantId { get; set; } 

    [ForeignKey("Project")] 
    public int ProjectId { get; set; } 

    [ForeignKey("Person")] 
    public int PersonId { get; set; } 
    [ForeignKey("Person")] 
    public int PersonTenantId { get; set; } // duplicate 


    public DateTime AddedDate{ get; set; } 

    public virtual Project Project { get; set; } 
    public virtual Person Person { get; set; } 

} 
+0

Зачем вам нужно сопоставление TenantId в ProjectPerson, у вас уже есть сопоставление в таблицах проектов и людей? Что касается ProjectPerson, TenantID не имеет значения. Его просто ассоциативная таблица и данный арендатор могут запросить только проекты или человека в их праве на аренду? Вы не нуждаетесь в этом TenancyID, чтобы быть частью этой таблицы, и в итоге вы получите соединение с тремя таблицами, если вы попытаетесь заставить его. В противном случае проверьте это https://febdev.wordpress.com/2013/01/30/entity-framework-mapping-references-with-composite-keys/ – rism

+0

@rism две причины: 1. без TenantId в ProjectPerson мы не можем создать ассоциацию внешних ключей в СУБД. 2. Данные арендатора должны иметь возможность перемещаться между базами данных. т.е. каждая запись должна быть уникальной. – Greatran

+0

Я выполнил инструкции на странице https://febdev.wordpress.com/2013/01/30/entity-framework-mapping-references-with-composite-keys/, но получил следующую ошибку: «Недостаточное сопоставление: внешний ключ должен быть сопоставлен для некоторых ассоциаций или EntitySets, участвующих в ассоциации внешних ключей на концептуальной стороне. « – Greatran

ответ

1

Используйте свободно API для повторного использования TentantId столбца как FK, содержащихся в таблице соединения. ProjectId также должен быть включен в PK таблицы соединений. Обратите внимание, что я изменил порядок столбцов составного первичного ключа, чтобы в качестве первого столбца был TenantId.

public class Person 
    { 
     [Key, Column(Order = 0)] 
     public int TenantId { get; set; } 
     [Key, Column(Order = 1)] 
     public int PersonId { get; set; } 

     public string Name { get; set; } 

     public virtual ICollection<ProjectPerson> ProjectPeople { get; set; } 
    } 

    public class Project 
    { 
     [Key, Column(Order = 0)] 
     public int TenantId { get; set; } 
     [Key, Column(Order = 1)] 
     public int ProjectId { get; set; } 

     public string Name { get; set; } 

     public virtual ICollection<ProjectPerson> ProjectPeople { get; set; } 
    } 

    public class ProjectPerson 
    { 
     [Key, Column(Order = 0)] 
     public int TentantId { get; set; } 
     [Key, Column(Order = 1)] 
     public int ProjectId { get; set; } 
     [Key, Column(Order = 2)] 
     public int PersonId { get; set; } 

     public DateTime AddedDate { get; set; } 

     public virtual Project Project { get; set; } 
     public virtual Person Person { get; set; } 
    } 


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

     modelBuilder.Entity<Project>() 
      .HasMany(pr => pr.ProjectPeople) 
      .WithRequired(pp => pp.Project) 
      .HasForeignKey(pp => new { pp.TentantId, pp.ProjectId }); 

     modelBuilder.Entity<Person>() 
      .HasMany(pe => pe.ProjectPeople) 
      .WithRequired(pp => pp.Person) 
      .HasForeignKey(pp => new { pp.TentantId, pp.PersonId }); 
    } 
Смежные вопросы