实体框架数据建模:2个外键和一个主键

时间:2016-10-07 16:06:54

标签: c# asp.net-mvc entity-framework npgsql composite-primary-key

我有以下表格:

    if(isset($_POST["time"])){ // Not Empty
      $sql2 = "SELECT * FROM MyTable WHERE time1='".$_POST['time']."' AND type1='".$_POST['type']."';
    } 
    else{ //Only select the type
      $sql2 = "SELECT * FROM MyTable WHERE type1='".$_POST['type']."';
    }

    $result1 = $conn->query($sql2);

if ($result1->num_rows > 0) {
    // output data of each row
    while($row = $result1->fetch_assoc()) {

        echo $row["name1"];

我将注册ID作为主键,但如何确保eventid和particpantid是唯一的?我已经想到了复合键,但我在注册时需要一个Id属性,因为我需要将它作为另一个类/表上的外键。

对于任何对我的dbcontext感兴趣的人都是这样的:

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

3 个答案:

答案 0 :(得分:0)

创建另一个包含EventId和PaticipantId作为Composite键的表,然后将该表id放入Registration表中。

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

答案 1 :(得分:0)

有许多方法可以确保EventId和PaticipantId的组合是独一无二的,有或没有触及你的模型。

可以在数据库中设置:您可以声明两个字段UNIQUE的组合,然后在应用程序中捕获错误并按照您的需要处理它。

您还可以使用检查组合是否存在的函数直接在应用程序内部进行验证。 (如果确实存在,则返回false)

您还可以在模型中添加另一个字段,一个字符串表示同一个fiel中的两个ID,并声明它是唯一的

事实上,你的问题有很多解决方案......选择更适合自己的方法。

答案 2 :(得分:0)

您应该在列EventId和ParticipantId

的组合上添加唯一键

由于您正在使用EF迁移,因此您可以将唯一键添加到模型中,然后让Entity Framework为您生成新的迁移。然后,此迁移将为数据库添加唯一键。根据您的实体框架版本,这将是不同的。

在Entity Framework Core 1.0.0中,这很简单:

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

使用Entity Framework 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
            }
        )
    );