2

各テーブルに対応する 2 つのテーブルとモデルがあります: Employee と EmployeeEducation では、EmployeeEducation テーブルから 2 つの外部キーがあります。教育ごとに異なるコンサルタントを配置できます。

[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.EmployeeおよびEmployeeEducation.Consultantナビゲーション プロパティから生成することはできません。これは、外部キー名をデータ注釈[ForeignKey("EmployeeId")]およびで定義したためです[ForeignKey("ConsultantId")]

では、EF はどのように関係を検出するのでしょうか。モデル クラスのナビゲーション プロパティを検査します。私たちはすでにそれを知ってEmployeeEducation.EmployeeおりEmployeeEducation.Consultant、問題になることはないので、どこかに 3 番目のナビゲーション プロパティが必要です。このナビゲーション プロパティに属するリレーションシップには、関連付けが終了している必要があります。これは、EFがテーブルにEmployeeEducation追加の外部キーが必要であることを明らかに推測しているためです。Employee_IdEmployeeEducation

Employee_Idという名前のため、このナビゲーション プロパティはクラスに含まれますEmployee。あなたを見るとInclude(a => a.EducationList)、にコレクションプロパティがあるようですEmployee

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

このコレクションは、3 番目の外部キーの原因である可能性が最も高いです。にナビゲーション プロパティが 1 つしかない場合EmployeeEducation(たとえば、 only のみ)、この場合、とが 1 つの関係のナビゲーション プロパティのペアであるとEmployeeEducation.EmployeeEF が推測するため、問題は発生しません。Employee.EducationListEmployeeEducation.Employee

2 つのナビゲーション プロパティがある場合、どちらもEmployeeEF を参照して、コレクションが 2 つのどちらにEmployee属しているかを判断できません。何らかのルールで 1 つを選択する代わりに、それらのいずれも選択せず、コレクションが 3 番目の関係に属していると想定します。

この問題を解決するには、コレクションを関連付ける 2 つの参照のどちらに EF でヒントを与える必要がありEmployeeEducationますか。たとえば[InverseProperty]、プロパティの 1 つ (両方ではない) の属性を使用します。

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

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

注意:には、指定された従業員の対象EducationListとなる のみが含まれますが、 は含まれません。そのためには、今回は注釈付きの 2 番目のコレクション プロパティが必要です。通常、1 つのエンティティの1 つのナビゲーション コレクションを、他のエンティティの2 つのナビゲーション参照に関連付けることはできません。選択肢は 2 つのコレクションか、まったくコレクションがないかのいずれかです。(後者の場合、問題は解消されますが、「含める」ことができるナビゲーション プロパティはもうありません。)EmployeeEducationEmployeeConsultantEmployee[InverseProperty]Consultant

于 2013-05-13T22:22:55.153 に答える