[英]EF Core Unique Constraint across multiple tables
How do I create/design the relationship and unique constraint: 如何创建/设计关系和唯一约束:
A PROJECT has many SUBJOBS. 一个项目有许多SUBJOBS。 A SUBJOB has many TASKS. SUBJOB有许多任务。 A TASK has a Number which must be unique across a single PROJECT. 任务具有一个编号,该编号在单个项目中必须唯一。
I tried the following for the relationship but I can't figure out how to enforce the unique constraint for Task.Number
and Project.ProjectId
: 我为关系尝试了以下方法,但是我不知道如何对Task.Number
和Project.ProjectId
实施唯一约束:
public class ProjectContext : DbContext
{
public DbSet<Project> Project { get; private set; }
public DbSet<SubJob> SubJob { get; private set; }
public DbSet<Task> Task { get; private set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Project>(b =>
{
b.HasKey(p => p.ProjectId);
b.HasAlternateKey(p => p.Code);
});
modelBuilder.Entity<SubJob>(b =>
{
b.HasKey(s => s.SubJobId);
b.HasOne(s => s.Project).WithMany(p => p.SubJobs).HasForeignKey(s => s.ProjectId);
b.HasAlternateKey(s => new { s.ProjectId, s.Code });
});
modelBuilder.Entity<Task>(b =>
{
b.HasKey(l => l.TaskId);
b.HasOne(l => l.SubJob).WithMany(s => s.Tasks).HasForeignKey(l => l.SubJobId);
});
}
}
public class Project
{
public int ProjectId { get; private set; }
public string Code { get; set; }
public ICollection<SubJob> SubJobs { get; private set; } = new List<SubJob>();
}
public class SubJob
{
public int SubJobId { get; private set; }
public int ProjectId { get; private set; }
public Project Project { get; set; }
public string Code { get; set; }
public ICollection<Task> Tasks { get; private set; } = new List<Task>();
}
public class Task
{
public int TaskId { get; private set; }
public int SubJobId { get; private set; }
public SubJob SubJob { get; set; }
public int Number { get; set; }
}
I see two possibilities. 我看到两种可能性。 Use natural keys for the child classes, so Subjob might be {ProjectId, JobCode} and Task might be {ProjectId, JobCode, Number}. 对子类使用自然键,因此Subjob可能是{ProjectId,JobCode},而Task可能是{ProjectId,JobCode,Number}。 But if the {ProjectId, Number} must be unique, then that would be the PK and JobCode would be a non-null FK, but not part of the PK. 但是,如果{ProjectId,Number}必须是唯一的,那么它将是PK,而JobCode将是非空FK,但不是PK的一部分。
Or, if your database supports indexed views you could create a view with a unique index on {ProjectId, Number}. 或者,如果数据库支持索引视图,则可以在{ProjectId,Number}上创建具有唯一索引的视图。
To define unique constraint on Tasks
table, you would need to get value of ProjectId
in Task
class. 要在Tasks
表上定义唯一约束,您需要在Task
类中获取ProjectId
值。 The modified Task
entity would look like this. 修改后的Task
实体看起来像这样。
public class Task
{
public int TaskId { get; private set; }
public int SubJobId { get; private set; }
public SubJob SubJob { get; set; }
public int Number { get; set; }
public int ProjectId { get; set; } // Added property
}
Since every Task
has a SubJob
and every SubJob
has a Project
, Task.ProjectId
should be equal to Task.SubJob.ProjectId
(which in turn takes value from SubJob.Project.ProjectId
). 由于每个Task
都有一个SubJob
,每个SubJob
都有一个Project
, Task.ProjectId
应该等于Task.SubJob.ProjectId
(后者从SubJob.Project.ProjectId
获取值)。 To make sure this value is passed around we can define a relationship between Task
& SubJob
to use composite keys like following 为了确保传递此值,我们可以定义Task
和SubJob
之间的关系以使用复合键,如下所示
modelBuilder.Entity<Task>(b =>
{
b.HasKey(l => l.TaskId);
b.HasOne(l => l.SubJob).WithMany(s => s.Tasks).HasForeignKey(l => new { l.SubJobId, l.ProjectId })
.HasPrincipalKey(l => new { l.SubJobId, l.ProjectId });
b.HasAlternateKey(t => new { t.Number, t.ProjectId });
});
Then we can define the unique constraint over Number
& ProjectId
using HasAlternateKey
. 然后,我们可以使用HasAlternateKey
在Number
& ProjectId
定义唯一约束。
You could also use Composite Keys with ProjectId
as being part but that could require to setup value generation for other part of PK. 您也可以使用带有ProjectId
复合键,但是这可能需要为PK的其他部分设置值生成。
Unless you really need unique constraint, consider using unique index. 除非您确实需要唯一约束,否则请考虑使用唯一索引。 More info can be found here 更多信息可以在这里找到
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.