【问题标题】:How to create grandparent foreign key in EFCORE如何在 EFCORE 中创建祖父母外键
【发布时间】:2022-01-08 21:54:29
【问题描述】:

我有一名员工,有一份按小时计酬的工作,每个小时有多个考勤卡。我希望将考勤卡链接到员工和每小时。

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

【问题讨论】:

    标签: entity-framework


    【解决方案1】:

    违反3NF,即重复数据可能导致数据异常等问题。一种技巧是将Employee FK 包含在Job 的复合PK 中。这样,当Timecard 具有到Job 的外键时,它也具有到Employee 的外键。也许您可以将工作代码用于第二个字段以包含在复合 Job PK 中或引用另一个实体,下面是一个示例,其中 PositionJob 的规范化详细信息,没有员工特定数据(例如每小时费率)和JobEmployeePosition 相关联,其中包含员工特定的详细信息:

    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();
    

    这可能需要一些调整,但这就是它的具体细节。

    【讨论】:

    • Job 在这里与 Hourly 的作用相同。你是正确的,时间卡应该是特定于员工的,而不是通过每小时/工作代理。我也遇到了迁移问题,不得不清空数据库。谢谢。
    猜你喜欢
    • 2011-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-09
    相关资源
    最近更新 更多