4

ビジネス要件は次のとおりです。

  • すべての従業員をデータベースに保存する必要がある
  • アシスタントがいる従業員もいれば、いない従業員もいます
  • 一部の従業員には複数のアシスタントがいます
  • アシスタントも社員です

明らかに、自己参照の状況が少しあります。しかし、典型的な「Employee-Manager」の状況との違いは、ここでは 1 人の Employee が 0 または複数のアシスタントを持つことができるということです。したがって、従業員と従業員のアシスタントの組み合わせは、従業EmployeeAssistantの 1 対多の関係で別のテーブルに格納する必要があります。しかし、Entity Framework 6 Code First でこれをモデル化する方法がわかりません。

私はこれから始めました:

public class Employee
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

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

   [ForeignKey("Assistant")]
   public int AssistantId { get; set; }
   public virtual Employee Assistant { get; set; }
}

しかし、コマンド中にエラーが発生しますUpdate-Database:

テーブル 'EmployeeAssistant' に FOREIGN KEY 制約 'FK_dbo.EmployeeAssistant_dbo.Employee_EmployeeId' を導入すると、サイクルまたは複数のカスケード パスが発生する可能性があります。ON DELETE NO ACTION または ON UPDATE NO ACTION を指定するか、他の FOREIGN KEY 制約を変更します。

私は何が欠けていますか?これに別の方法でアプローチする必要がありますか?

4

2 に答える 2

2

各従業員には 1 人以上のアシスタントがいる可能性があり (各アシスタントには 1 人以上の従業員がいる)、全員が従業員であるため、最も単純な解決策はアシスタントと従業員の 2 つのコレクションを持つ 1 つのクラスであり、関係はフレームワークによって管理されます。

public class Employee
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public ICollection<Employee> Assistants { get; set; }
    public ICollection<Employee> Employees { get; set; }
}

パッケージ マネージャー コンソールを使用して移行を追加すると、従業員用と多対多関係用の 2 つのテーブルが自動的に作成されます。

あとは、Include 拡張メソッドを使用して、関連するアシスタントや従業員を見つけるだけです。

db.Employees.Where(x=>x.Id==id).Include(x=>x.Assistants).FirstOrDefault()

および/または

db.Employees.Where(x=>x.Id==id).Include(x=>x.Employees).FirstOrDefault()

于 2016-08-29T07:03:51.073 に答える
0

このリンクに基づいてFOREIGN KEY 制約を導入すると、サイクルまたは複数のカスケード パスが発生する可能性があります - なぜですか?

EmployeeAssistantコードでを削除すると、 2 つのカスケード 削除パスが発生するようです。

次のような構造を提案します。

編集後

public class Employee
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public List<EmployeeAssistant> Assistants { get; set; } //if an employee has no assistants this List can easily just be empty
    OR
    public ICollection<EmployeeAssistant> Assistants { get; set; } // depending on your architecture, choose the one that would suit you better
}
public class EmployeeAssistant
{
   [ForeignKey("Employee")]
   public int EmployeeId { get; set; } //this is the employee who 'has' this assistant
   public virtual Employee Employee { get; set; }

   public int Id { get; set; }  //this is the assistant's own information - identical to employee's basic info
   public string FirstName { get; set; }
   public string LastName { get; set; }
}

しばらく頭を悩ませた後、従業員という 1 つのクラスだけが必要な可能性を思いつきましたが、IsAssistantこの従業員がアシスタントであるかどうかを示すbool が含まれており、AssistantEmployeeIdこれは「持っている」従業員の従業員 ID です。このアシスタント。例えば:

public class Employee
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public bool IsAssistant { get; set; }
    public int EmployeeAssistantID { get; set; }
}

この2番目の方法は非常に面倒で、おそらくあなたのニーズに合わないことはわかっていますが、個人的には、常に最初にデータベーステーブルを作成してから、「データベースからモデルを生成」を実行するため、コードファーストのアプローチには慣れていません.

于 2016-08-29T04:50:30.153 に答える