繁体   English   中英

使用非主键列的实体框架自引用

[英]Entity Framework Self Referencing Using Non-Primary Key Column

我有一个自我参考的员工表,用于确定组织结构。 我尝试使用Code-First(POCO)进行设置时遇到了一些麻烦。

员工记录同时具有“位置”字段和“ ReportsTo”字段,并且这两列都不是主键(employee.id)。

“08294”是“ 上级 ”的价值的员工,是员工的以“08294”,“ 位置 ”值直接报告的雇员。

谁能流利地提供一些有关如何首先使用EF代码进行设置的信息...可以吗?

我尝试了下面的代码,但出现错误:

Employee_Employees_Source_Employee_Employees_Target ::引用约束的“从属角色”中所有属性的类型必须与“主体角色”中相应的属性类型相同。 在参照约束“ Employee_Employees”中,实体“ Employee”的属性“ ReportsTo”的类型与实体“ Employee”的属性“ Id”的类型不匹配。

Employee.cs

public class Employee
{
     public int Id  { get; set; } //pk 
     public string Position { get; set; } // i.e. 06895
     public string ReportsTo{ get; set; } // i.e. 08294         

     public virtual Employee Supervisor { get; set; }
     public virtual ICollection<Employee> Employees { get; set; }
}

的DbContext

modelBuilder.Entity<Employee>()
                .HasMany(e => e.Employees)
                .WithOptional(e => e.Supervisor)
                .HasForeignKey(e => e.ReportsTo);

我认为最重要的是,我希望POCO不受EF“填充”的影响,并能够执行以下操作:

employee.IsSupervisor(); // based on child employee count. 

问题出在关系配置中。 如果要在不使用FK的情况下配置一对多关系,则可以执行以下操作:

modelBuilder.Entity<Employee>()
            .HasMany(e => e.Employees)
            .WithOptional(e => e.Supervisor);

现在,如果要使用FK属性,请将此属性添加到模型类中:

public class Employee
{
  //...
  public int SupervisorId  { get; set; }
}

并以这种方式映射您的关系:

modelBuilder.Entity<Employee>()
            .HasMany(e => e.Employees)
            .WithOptional(e => e.Supervisor)
            .HasForeignKey(e => e.SupervisorId);

为了解决与ReportToPosition属性有关的问题,我认为您应该在代码中处理该逻辑。 如果您想根据“ Employees属性的数量来了解“ Employee是否为主管,则可以使用“未映射”属性:

 public class Employee
{
  [NotMapped]
  public bool IsSupervisor
  {
     get
     {
         return Employess.Count>0
     }
  }
}

您可以使用Fluent Api进行相同的操作:

modelBuilder.Entity<Employee>().Ignore(e => e.IsSupervisor);

PS:请记住在类的构造函数中初始化Employees

您得到的错误是因为它试图将int类型的PK映射到string类型的FK。 您所有关键字段的用户int

然后,您需要像这样声明您的OnModelBuilding:

modelBuilder.Entity<Employee>()
.HasOptional(e => e.Supervisor)
.WithMany()
.HasForeignKey(s => s.ReportsTo);

要获得类似于IsSupervisor()东西,您可以利用局部类。 创建另一个类文件,它是一个public partial class Employee (并将原始的public partial class Employee修改为部分),然后在新文件中添加一个可以执行所需操作的属性,并使用[NotMapped]属性对其进行[NotMapped] 您的外观可能类似于public bool IsSupervisor {get { return (Employees == null) ? false : true; } set {} } public bool IsSupervisor {get { return (Employees == null) ? false : true; } set {} } public bool IsSupervisor {get { return (Employees == null) ? false : true; } set {} }新的局部类是您可以在不更改EF类的情况下为POCO做任何您想做的事情(不过请确保使用[NotMapped] )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM