0

我有以下表格:實體框架數據建模:2個外鍵和主鍵

public class Event { 
    public int Id {get;set;} 
} 

public class Participant{ 
    public int Id {get;set;} 
} 

public class Registration{ 
    public int Id {get;set;} 
    public int EventId {get;set;} 
    public int PaticipantId {get;set;} 
} 

我的註冊ID作爲主鍵,但如何確保該事件ID和particpantid是獨特?我想到了複合鍵,但是我需要在註冊時使用Id屬性,因爲我需要將它作爲另一個類/表的外鍵。

約我的DbContext人好奇的是這樣的:

modelBuilder.Entity<Registration>() 
       .HasRequired(e => e.Participant) 
       .WithMany(u => u.Events) 
       .HasForeignKey(e => e.ParticipantId); 

      modelBuilder.Entity<Registration>() 
       .HasRequired(e => e.Event) 
       .WithMany(u => u.Participants) 
       .HasForeignKey(e => e.EventId); 
+1

你想組合eventId和participantId是唯一的嗎?數據庫中這兩列的唯一鍵將保證這一點,或者這不是你要求的嗎? – HansVG

+0

你在談論複合鍵嗎?我在想,但我需要一個單獨的唯一身份證,除了他們的組合作爲一個ID。這就是Registration.Id的用途。但我需要確保EventId和ParticipantId是唯一的。 – gdubs

+0

你的RegistrationId是你的主鍵。默認情況下,postgres將爲此列創建唯一的約束。然後,在EventId和ParticipantId的列上添加一個唯一的密鑰(在您的數據庫https://www.postgresql.org/docs/9.6/static/indexes- u​​nique.html中)。這樣您的registrationId是唯一的,組合EventId,ParticipantId也是唯一的。如果您正在使用實體框架遷移,則可以在您的dbcontext類中指示您希望在這兩列上使用唯一鍵,並讓實體框架爲您生成遷移(或將其手動添加到遷移) – HansVG

回答

0

創建一個包含EVENTID和PaticipantId爲複合鍵,然後把該表ID到您的註冊表中的另一表。

public class Event { 
    public int Id {get;set;} 
} 

public class Participant{ 
    public int Id {get;set;} 
} 

public class NewTable{ 
    public int Id {get;set;} 
    public int EventId {get;set;} 
    public int PaticipantId {get;set;} 
} 

public class Registration{ 
    public int Id {get;set;} 
    public int NewTableId {get;set;} 
} 
+0

你的意思是在NewTable上有一個Id嗎?如果你這樣做,似乎已經是註冊表了。我需要Newtable才能擁有EventId和ParticipantId的獨特組合。假設NewTable就是這樣。我如何使用將增加每個插入的Id來創建組合鍵? – gdubs

+0

爲什麼你需要使註冊表的ID成爲主鍵,因爲它會增加每一次? – user3754008

+0

是的,我需要一個多對多的關係到另一個表 – gdubs

0

有actualy很多方法可以確保EVENTID和PaticipantId的組合是有或沒有,甚至觸及你的模型是獨一無二的。

它可以在您的數據庫中設置:您可以聲明兩個字段UNIQUE的組合,然後在您的應用程序中捕獲錯誤並按照您的要求處理它。

您還可以直接在應用程序內部使用檢查組合是否存在的函數進行驗證。 (返回false,如果不存在的話)

您也可以在模型中添加一個字段,表示在同一fiels兩個ID的字符串,並宣佈它獨特的

事實上,還有噸的解決方案,爲您的問題...選擇對自己來說更容易。

0

您應該列EVENTID的組合和ParticipantId

由於您使用的EF遷移添加的唯一密鑰,您可以添加獨特的關鍵是你的模型,並讓實體框架爲你生成一個新的遷移之後。此遷移將爲您的數據庫添加一個唯一的密鑰。取決於你的實體框架版本,這將會有所不同。

在實體框架的核心1.0.0這很簡單:

modelBuilder.Entity<Registration>().HasIndex(x => new { x.ParticipantId, x.EventId}).IsUnique(); 

當使用實體框架6,你可以使用註釋或流暢API(雖然比較詳細):

使用註釋:

public class Registration 
{ 
    public int Id {get;set;} 
    [Index("UQ_Registration_EventId_ParticipantId", 1, IsUnique = true)] 
    public int EventId {get;set;} 
    [Index("UQ_Registration_EventId_ParticipantId", 2, IsUnique = true)] 
    public int PaticipantId {get;set;} 
} 

或者流利API:

string uniqueIndex = "UQ_Registration_EventId_ParticipantId"; 

modelBuilder.Entity<Registration>().Property(t => t.EventId) 
    .HasColumnAnnotation(
     IndexAnnotation.AnnotationName, 
     new IndexAnnotation(
      new IndexAttribute(uniqueIndex) 
      { 
       IsUnique = true, 
       Order = 1 
      } 
     ) 
    ); 

modelBuilder.Entity<Registration>().Property(t => t.ParticipantId) 
    .HasColumnAnnotation(
     IndexAnnotation.AnnotationName, 
     new IndexAnnotation(
      new IndexAttribute(uniqueIndex) 
      { 
       IsUnique = true, 
       Order = 2 
      } 
     ) 
    ); 
+0

好的,這似乎很直接,唯一的問題是uniqueIndex,是我需要自己生成的東西嗎?此外,該ID會自動生成? – gdubs

+0

沒有自動生成的ID。唯一鍵只是禁止重複出現在表格中的EventId和ParticipantId組合的約束。它本身沒有Id。唯一約束確保包含在一列或一組列中的數據(在本例中爲您的兩個外鍵標識EventId和ParticipantId)在表中的所有行中都是唯一的。 – HansVG