4

简而言之,以下是业务需求:

  • 所有员工都需要存储在数据库中
  • 有些员工有助理,有些没有
  • 一些员工有不止一名助理
  • 助理也是雇员

显然有一点自我参照的情况。但与典型的“员工-经理”情况不同的是,一个员工可以有 0 个或多个助手。因此,Employee和员工助手的组合需要以EmployeeEmployeeAssistant之间的一对多关系存储在单独的表中。但是我很困惑如何在 Entity Framework 6 Code First 中对此进行建模。

我从这个开始:

public class Employee
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class EmployeeAssistant
{
   [ForeignKey("Employee")]
   public int EmployeeId { get; set; }
   public virtual Employee Employee { get; set; }

   [ForeignKey("Assistant")]
   public int AssistantId { get; set; }
   public virtual Employee Assistant { get; set; }
}

Update-Database但我在命令期间收到错误:

在表“EmployeeAssistant”上引入 FOREIGN KEY 约束“FK_dbo.EmployeeAssistant_dbo.Employee_EmployeeId”可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。

我错过了什么?我应该以不同的方式处理这个问题吗?

4

2 回答 2

2

由于每个员工可能有一个或多个助手(每个助手将有一个或多个员工)并且都是员工,因此最简单的解决方案是一个类,其中包含助手和员工的两个集合,并且关系将由框架管理:

public class Employee
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public ICollection<Employee> Assistants { get; set; }
    public ICollection<Employee> Employees { get; set; }
}

当您使用包管理器控制台添加迁移时,它会自动创建两个表,一个用于员工,另一个用于多对多关系。

那么您所要做的就是使用 Include 扩展方法找到相关的助手和/或员工。

db.Employees.Where(x=>x.Id==id).Include(x=>x.Assistants).FirstOrDefault()

和/或

db.Employees.Where(x=>x.Id==id).Include(x=>x.Employees).FirstOrDefault()

于 2016-08-29T07:03:51.073 回答
0

基于此链接Introducing FOREIGN KEY constraint 可能会导致循环或多个级联路径 - 为什么?

似乎如果你EmployeeAssistant用你的代码删除一个,它会导致两个级联删除路径

我会建议这样的结构:

编辑后

public class Employee
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public List<EmployeeAssistant> Assistants { get; set; } //if an employee has no assistants this List can easily just be empty
    OR
    public ICollection<EmployeeAssistant> Assistants { get; set; } // depending on your architecture, choose the one that would suit you better
}
public class EmployeeAssistant
{
   [ForeignKey("Employee")]
   public int EmployeeId { get; set; } //this is the employee who 'has' this assistant
   public virtual Employee Employee { get; set; }

   public int Id { get; set; }  //this is the assistant's own information - identical to employee's basic info
   public string FirstName { get; set; }
   public string LastName { get; set; }
}

经过一段时间的脑筋急转弯,我什至想出了一个可能性,你只需要一个类,Employee,但它包含一个IsAssistant表示该员工是否是助理的 bool,AssistantEmployeeId它是“有”的员工的员工 ID这个助理。例如:

public class Employee
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public bool IsAssistant { get; set; }
    public int EmployeeAssistantID { get; set; }
}

我知道第二种方法非常混乱,可能不适合您的需求,但我个人总是先创建数据库表,然后执行“从数据库生成模型”,所以我对代码优先方法缺乏经验。

于 2016-08-29T04:50:30.153 回答