2

我有两个表和对应于每个表的模型: Employee 和 EmployeeEducation 在 EmployeeEducation 我有来自表 Employee 的 2 个外键:顾问的 ID 和拥有教育的实际员工的 ID。每个教育可以有不同的顾问。

[Required(ErrorMessage = "Contact Admin")]
[Display(Name = "Consultant")]
public int? ConsultantId { get; set; }
*emphasized text*
[Required(ErrorMessage = "Contact Admin")]
public int? EmployeeId { get; set; }

对于每个 id,我都有这些对象可以到达对象

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

[ForeignKey("ConsultantId")]
public virtual Employee Consultant { get; set; }

当我运行代码并尝试通过顾问对员工进行教育时,它给了我以下异常和内部异常。

EntityCommandExecutionException 
{"An error occurred while executing the command definition. See the inner exception for details."}

Inner exception: SqlCeException
{"The column name is not valid. [ Node name (if any) = Extent1,Column name = Employee_Id ]"}

但是当我删除顾问对象时,它不会给出异常。我该如何解决这个问题,以便我可以同时访问顾问和员工本身?

异常发生在 DetailsEducation.cshtml 中:

@{ if (Model.EducationList == null || !Model.EducationList.Any())
    { 

以下是 EducationList 的填充方式:

public ActionResult DetailsEducation(int id) 
{ 
  Employee employee = _work.EmployeeRepository.GetSet()
    .Include(a => a.EducationList)
    .Include(a => a.EducationList.Select(c => c.University))
    .Include(a => a.EducationList.Select(c => c.Department))
    .FirstOrDefault(a => a.Id == id); 
  return PartialView("_DetailsEducation", employee);
}
4

1 回答 1

3

列名 = Employee_Id

当 Entity Framework 创建一个 SQL 查询时,其列名中有一个(意外的)下划线的外键,它几乎总是表明 EF 按约定推断关系,这与您使用注释或 Fluent 定义的关系不同API。

此外键不能来自EmployeeEducation.EmployeeEmployeeEducation.Consultant导航属性,因为对于那些您已经使用数据注释[ForeignKey("EmployeeId")]和定义了外键名称的人[ForeignKey("ConsultantId")]

现在,EF 如何检测关系?它检查模型类中的导航属性。我们已经知道这一点EmployeeEducation.Employee并且EmployeeEducation.Consultant不会是问题所在,因此某处必须存在第三个导航属性。属于此导航属性的关系必须以关联结尾,因为 EF 显然推断出表EmployeeEducation中需要额外的外键。Employee_IdEmployeeEducation

由于名称 - Employee _Id - 此导航属性将在您的类Employee中。看着你的Include(a => a.EducationList)你似乎有一个集合属性Employee

public SomeCollectionType<EmployeeEducation> EducationList { get; set; }

此集合很可能导致第三个外键。如果您在 中只有一个导航属性EmployeeEducation,例如 only EmployeeEducation.Employee,则不会出现问题,因为 EF 在这种情况下会推断出Employee.EducationList并且EmployeeEducation.Employee是单个关系的一对导航属性。

如果您有两个都引用 EF 的导航属性,Employee则无法确定集合Employee属于这两者中的哪一个。它不选择任何规则,而是不选择其中任何一个,并假设该集合属于第三种关系。

要解决该问题,您必须 EF 提示您希望将集合与两个引用中的EmployeeEducation哪一个相关联,例如,通过[InverseProperty]在其中一个属性上使用属性(但不能同时使用两者):

[ForeignKey("EmployeeId"), InverseProperty("EducationList")]
public virtual Employee Employee { get; set; }

[ForeignKey("ConsultantId")]
public virtual Employee Consultant { get; set; }

注意:EducationList遗嘱只包含EmployeeEducation给定员工的 s Employee,但不包含 s Consultant。为此,您将需要第二个集合属性,此时Employee带有[InverseProperty]注释Consultant。通常,您不能将一个实体中的一个导航集合与另一个实体中的两个导航引用相关联。您唯一的选择是两个集合或根本没有集合。(在后一种情况下,顺便说一句,您的问题也会消失,但是您将不再拥有可以“包含”的导航属性。)

于 2013-05-13T22:22:55.153 回答