如何在 EFCORE 中创建祖父母外键
How to create grandparent foreign key in EFCORE
我有一名员工,有一份按小时计酬的工作,每个小时都有多个考勤卡。我希望工时卡 link 给员工和小时工。
public class Employee
{
public int Id { get; set; }
}
public class Hourly
{
public int EmployeeId { get; set; }
public List<Timecard> Timecards{ get; set; }
}
public class Hourly
{
public int HourlyId{ get; set; }
public int EmployeeId { get; set; }
}
如何在 EF 中指定此关系。
该代码似乎设置了 employeeID,但导致迁移出现问题,Hourly 现在设置为 null。
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Timecard>()
.HasOne<HourlyPC>()
.WithMany(pc => pc.Timecards)
.HasForeignKey(t => t.EmployeeId)
.HasPrincipalKey(pc => pc.EmployeeId);
}
违反3NF,意思是重复的数据会导致数据异常等问题。一种破解方法是将 Employee
FK 包含在 Job
的复合 PK 中。这样,当 Timecard
有 Job
的外键时,它也有 Employee
的外键。也许您可以将工作代码用于第二个字段以包含在复合 Job
PK 中或引用另一个实体,下面是一个示例,其中 Position
是 Job
的规范化详细信息w/o 员工特定数据(例如小时费率)和 Job
将 Employee
与具有员工特定详细信息的 Position
相关联:
public class Employee
{
public int Id { get; set; }
}
public class Job
{
public int EmployeeId { get; set; }
public Employee Employee { get; set; }
public string PositionId { get; set; }
public Position Position { get; set; }
public ICollection<TimeCard> TimeCards { get; set; }
public decimal HourlyRate { get; set; }
}
public class TimeCard
{
public Id { get; set; }
public int EmployeeId { get; set; }
public Employee Employee { get; set; }
public string PositionId { get; set; }
public Job Job { get; set; }
}
配置:
// configure Job
// configure relationshipt to Position
modelBuilder.Entity<Job>()
.HasOne(j => j.Position)
.WithMany()
.IsRequired();
// configure relationship to Employee
modelBuilder.Entity<Job>()
.HasOne(j => j.Employee)
.WithMany()
.IsRequired();
// create composite PK using the two FK's
modelBuilder.Entity<Job>()
.HasKey(j => new { j.EmployeeId, j.PositionId });
// configure TimeCard
// configure nav prop to Employee
modelBuilder.Entity<TimeCard>()
.HasOne(tc => tc.Employee);
// configure relationship with Job
modelBuilder.Entity<TimeCard>()
.HasOne(tc => tc.Job)
.WithMany(j => j.TimeCards)
.HasForeignKey(tc => new { tc.EmployeeId, tc.PositionId })
.IsRequired();
这可能需要一些调整,但这就是它的基本要素。
我有一名员工,有一份按小时计酬的工作,每个小时都有多个考勤卡。我希望工时卡 link 给员工和小时工。
public class Employee
{
public int Id { get; set; }
}
public class Hourly
{
public int EmployeeId { get; set; }
public List<Timecard> Timecards{ get; set; }
}
public class Hourly
{
public int HourlyId{ get; set; }
public int EmployeeId { get; set; }
}
如何在 EF 中指定此关系。
该代码似乎设置了 employeeID,但导致迁移出现问题,Hourly 现在设置为 null。
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Timecard>()
.HasOne<HourlyPC>()
.WithMany(pc => pc.Timecards)
.HasForeignKey(t => t.EmployeeId)
.HasPrincipalKey(pc => pc.EmployeeId);
}
违反3NF,意思是重复的数据会导致数据异常等问题。一种破解方法是将 Employee
FK 包含在 Job
的复合 PK 中。这样,当 Timecard
有 Job
的外键时,它也有 Employee
的外键。也许您可以将工作代码用于第二个字段以包含在复合 Job
PK 中或引用另一个实体,下面是一个示例,其中 Position
是 Job
的规范化详细信息w/o 员工特定数据(例如小时费率)和 Job
将 Employee
与具有员工特定详细信息的 Position
相关联:
public class Employee
{
public int Id { get; set; }
}
public class Job
{
public int EmployeeId { get; set; }
public Employee Employee { get; set; }
public string PositionId { get; set; }
public Position Position { get; set; }
public ICollection<TimeCard> TimeCards { get; set; }
public decimal HourlyRate { get; set; }
}
public class TimeCard
{
public Id { get; set; }
public int EmployeeId { get; set; }
public Employee Employee { get; set; }
public string PositionId { get; set; }
public Job Job { get; set; }
}
配置:
// configure Job
// configure relationshipt to Position
modelBuilder.Entity<Job>()
.HasOne(j => j.Position)
.WithMany()
.IsRequired();
// configure relationship to Employee
modelBuilder.Entity<Job>()
.HasOne(j => j.Employee)
.WithMany()
.IsRequired();
// create composite PK using the two FK's
modelBuilder.Entity<Job>()
.HasKey(j => new { j.EmployeeId, j.PositionId });
// configure TimeCard
// configure nav prop to Employee
modelBuilder.Entity<TimeCard>()
.HasOne(tc => tc.Employee);
// configure relationship with Job
modelBuilder.Entity<TimeCard>()
.HasOne(tc => tc.Job)
.WithMany(j => j.TimeCards)
.HasForeignKey(tc => new { tc.EmployeeId, tc.PositionId })
.IsRequired();
这可能需要一些调整,但这就是它的基本要素。