实体框架数据建模:2个外键和一个主键
本文关键字:一个 实体 建模 数据 2个 框架 | 更新日期: 2023-09-27 18:12:15
我有以下表格:
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作为主键,但是如何确保eventid和participant是唯一的呢?我已经考虑过复合键,但是我需要注册上的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);
创建另一个表,其中包含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;}
}
实际上有许多方法可以确保EventId和PaticipantId的组合是唯一的,无论是否触及您的模型。
它可以在你的数据库中设置:你可以声明两个字段的组合UNIQUE,然后在你的应用程序中捕获错误并按你想要的方式处理它。
还可以在应用程序中直接使用一个函数来验证组合是否存在。(如果存在则返回false)
您还可以在您的模型中添加另一个字段,一个字符串表示相同字段中的两个id,并声明它是唯一的
事实上,有很多方法可以解决你的问题。您应该在列EventId和ParticipantId的组合上添加一个唯一键
由于您正在使用EF迁移,您可以向您的模型添加唯一的键,并让实体框架在之后为您生成一个新的迁移。然后,此迁移将向数据库添加一个惟一键。根据您的实体框架版本,这将是不同的。
在Entity Framework Core 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
}
)
);