[英]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);
为了解决与ReportTo
和Position
属性有关的问题,我认为您应该在代码中处理该逻辑。 如果您想根据“ 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.