我有一个自我引用的员工表来确定组织结构。我在尝试使用Code-First(POCO)流畅地设置它时遇到了一些麻烦。
员工记录包含"职位" 字段和" ReportsTo" 字段,且两个列都不是主键(employee.id)。
拥有" ReportsTo "价值" 08294 " ,是员工直接报告的员工,其职位为职位"价值" 08294 "。
任何人都可以提供一些关于如何首先使用EF代码进行设置的信息,流利地说......有可能吗?
我尝试了下面的代码并收到错误:
Employee_Employees_Source_Employee_Employees_Target ::所有类型 参照约束的从属角色中的所有属性都必须 与主体角色中的相应属性类型相同。 财产的类型' ReportsTo'实体'员工'不匹配 财产的类型' Id'实体'员工'在参考 约束' Employee_Employees'。
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&#34;东西&#34;并能够做类似的事情:
employee.IsSupervisor(); // based on child employee count.
答案 0 :(得分:2)
问题出在关系配置中。如果要在不使用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
属性相关的问题,我认为您应该在代码中处理该逻辑。如果您想知道Employee
是否是基于Employees
属性计数的主管,您可以使用NotMapped属性:
public class Employee
{
[NotMapped]
public bool IsSupervisor
{
get
{
return Employess.Count>0
}
}
}
您可以使用Fluent Api执行相同的操作:
modelBuilder.Entity<Employee>().Ignore(e => e.IsSupervisor);
PS:请记住在您的class'constructor中初始化Employees
。
答案 1 :(得分:-1)
您得到的错误是因为它试图将int
类型的PK映射到string
类型的FK。用户int
用于所有关键字段。
然后,你需要像这样声明你的OnModelBuilding:
modelBuilder.Entity<Employee>()
.HasOptional(e => e.Supervisor)
.WithMany()
.HasForeignKey(s => s.ReportsTo);
要获得类似IsSupervisor()
的内容,您可以利用部分类。创建另一个类文件public partial class Employee
(并将原始文件修改为部分文件),然后在新文件中添加一个可以执行任何操作的属性,并使用[NotMapped]
属性进行修饰。您可能看起来像public bool IsSupervisor {get { return (Employees == null) ? false : true; } set {} }
新的分部类是您可以在不更改EF类的情况下为POCO执行任何操作的地方(尽管请确保使用[NotMapped]
)。