如何在 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 中。这样,当 TimecardJob 的外键时,它也有 Employee 的外键。也许您可以将工作代码用于第二个字段以包含在复合 Job PK 中或引用另一个实体,下面是一个示例,其中 PositionJob 的规范化详细信息w/o 员工特定数据(例如小时费率)和 JobEmployee 与具有员工特定详细信息的 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();

这可能需要一些调整,但这就是它的基本要素。