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