我有两个表和与每个表相对应的模型: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);
}

最佳答案

列名称= Employee_Id


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

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

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

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

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将仅包含给定雇员为EmployeeEducationEmployee,而不包含Consultant。为此,您这次需要在Employee中的第二个collection属性,并且在[InverseProperty]上带有Consultant批注。通常,您不能将一个实体中的一个导航集合与另一个实体中的两个导航引用相关联。您唯一的选择是两个集合或根本没有集合。 (在后一种情况下,您的问题也将消失,但是您将不再具有导航属性,可以“包含”。)

关于c# - 同一表异常中的ASP.NET MVC 3.0 2外键,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16515679/

10-11 08:56