ASP.NET MVC 3.0 2外键来自同一个表异常

时间:2013-05-13 05:58:54

标签: c# entity-framework

我有两个表和模型对应每个表: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 ]"}

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

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);
}

1 个答案:

答案 0 :(得分:3)

  

列名= Employee_Id

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

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

现在,EF如何检测关系?它检查模型类中的导航属性。我们已经知道EmployeeEducation.EmployeeEmployeeEducation.Consultant不是问题所在,因此某处必须有第三个导航属性。属于此导航属性的关系必须在EmployeeEducation中具有关联结束,因为EF显然需要在Employee_Id表中推断出需要额外的外键EmployeeEducation

由于名称 - 员工 _Id - 此导航属性将位于您的班级Employee中。查看Include(a => a.EducationList)您似乎在Employee中有一个集合属性:

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

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

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

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

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

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

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