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

本文关键字:异常 MVC NET ASP | 更新日期: 2023-09-27 18:13:11

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

但是当我删除顾问对象时,它没有给出异常。我如何解决这个问题,使我能够同时访问顾问和员工本身?

异常发生在detailseduction .cshtml:

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

下面是如何填充教育列表:

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

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

列名= Employee_Id

当实体框架创建一个带有列名称中有一个(意外的)下划线的外键的SQL查询时,它几乎总是一个指示符,EF根据约定推断出一种关系,这是另一种关系,而不是您用注释或Fluent API定义的关系。

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

那么EF是如何检测关系的呢?它会检查模型类中的导航属性。我们已经知道EmployeeEducation.EmployeeEmployeeEducation.Consultant不可能是问题,所以必须在某个地方有第三个导航属性。属于这个导航属性的关系必须有一个以EmployeeEducation结尾的关联,因为EF显然推断需要在EmployeeEducation表中增加一个外键Employee_Id

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

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

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

如果你有两个导航属性都指向Employee, EF不能决定Employee中的集合属于哪一个。它不按照任何规则选择一个,而是不选择任何一个,并假设集合属于第三个关系。

要解决这个问题,你必须给出一个提示,在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中添加第二个集合属性,这次在Consultant上使用[InverseProperty]注释。通常不能将一个实体中的一个导航集合与另一个实体中的两个导航引用相关联。你唯一的选择是要么两个集合,要么根本不集合。(在后一种情况下,您的问题也会消失,顺便说一下,但您将不再拥有导航属性,您可以"包含"。)