2017-07-27 14 views
-4

関連するエンティティを持つエンティティを両方とも1つのDbSet.Add呼び出しに挿入する必要があります。EF6 - ナビゲーションプロパティのみで関連するエンティティを持つエンティティを挿入するときのエラー

public class Course 
{ 
    public Course() { } 
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public int ID { get; set; } 
    ... 
    public virtual ICollection<CourseProfesor> Profesors { get; set; } 
} 

public class CourseProfesor 
{ 
    public CourseProfesor() { } 
    [Key] 
    public int ID { get; set; } 
    [Required, Index, Column(Order = 0)] 
    public int CourseID { get; set; } 
    [Required, Index, Column(Order = 1)] 
    public int ProfesorID { get; set; } 
    ... 
    [ForeignKey("CourseID")] 
    public virtual Course Course { get; set; } 
    [ForeignKey("ProfesorID")] 
    public virtual Profesor Profesor { get; set; } 
} 

マッピング:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<Course>().HasMany(x => x.Profesors).WithRequired(x => x.Course); 
    modelBuilder.Entity<CourseProfesor>().HasRequired(x => x.Course).WithMany(x => x.Profesors); 
    modelBuilder.Entity<CourseProfesor>().HasRequired(x => x.Profesor).WithMany(x => x.Courses); 
} 

コントローラー:

一対多コースとCourseProfesor間は

エンティティ(CourseProfesorエンティティ接続コースとProfesorsです)

public ActionResult Add(Course course, int profesorId = 0) 
{ 
    if (profesor > 0) 
    { 
     course.Profesors = new List<CourseProfesor>(); 
     course.Profesors.Add(new CourseProfesor() { Course = course, CourseID = 0, ProfesorID = profesorId, From = DateTime.Now, Role = ... }); 
    } 
    Facade.Create(course); 
    return Json(new {statusText = "Course Added"}); 
} 

Facade.Create(エンティティ)が順番に

DbContext.Set(entity.GetType()).Add(entity) 

私が得る例外呼び出すCreateCommand実行:

データベースへの変更が正常にコミットされたのが、更新中にエラーが発生しましたオブジェクトコンテキスト。 ObjectContextが矛盾した状態になっている可能性があります。内部例外メッセージ:参照整合性制約違反が発生しました:リレーションシップの一方の「Course.ID」のプロパティ値が、他方の「CourseProfesor.CourseID」のプロパティ値と一致しません。

CourseProfesor.CourseIDを割り当てる方法は、コースのIDがまだわからない場合、どちらも新しいエンティティですか?
コントローラーコードでわかるように、私はナビゲーションプロパティーだけを設定することでそれを解決しました。それに応じて、EFはそれに応じて外部キーを自動入力します。
これは重要です:これは私がEF5はなかったがEF6がその例外をスローする理由

どれでも手がかりをEF6するために更新した後、そのエラーを得たEF5、に罰金働いていましたか?最初にコースを作成しなくても、それからCourseProfesor関係エンティティを作成することなくそれを解決する方法はありますか?

+0

エンティティマッピング/設定とエンティティクラスを設定する必要があります。 EF6はこれらをうまく処理しますが、エンティティの関係とキー生成に関する規則について十分な情報があることを保証する必要があります。 –

+0

ありがとうございます。私はエンティティと設定で質問を編集しました。申し訳ありません、私の最初の質問です。 – Lucio

答えて

0

物事のカップルスタンドアウト:

course.Profesors.Add(new CourseProfesor() { Course = course, CourseID = 0, ProfesorID = profesorId, From = DateTime.Now, Role = ... }); 

ナビゲーションプロパティを使用して、私は離れて実体におけるFKSのフィールドを定義から操縦していますが、それらを定義する必要がある場合、あなたはそれらを設定することは避けてください。ナビゲーションプロパティのみを使用します。このコースをCourseProfessorsに渡してそれを消費すると、ProfessorIDセットがありますが、教授のリファレンスはありませんので、FKを設定すると誤解を招く可能性があります。

あなたの具体的な問題については、前述のCourseID = 0と、CourseとCourseProfessorの間の双方向マッピングが考えられます。

modelBuilder.Entity<Course>().HasMany(x => x.Profesors).WithRequired(x => x.Course); 
//modelBuilder.Entity<CourseProfesor>().HasRequired(x => x.Course).WithMany(x => x.Profesors); 
modelBuilder.Entity<CourseProfesor>().HasRequired(x => x.Profesor).WithMany(x => x.Courses); 

この冗長マッピングを削除してみてください。

また、リンクテーブルの定義にはPKとしてのIDがありますが、生成オプションでは設定されていません。 2つのFKはOrder = 0とOrder = 1も設定されていますが、PKを考慮せずに奇妙に見えますか?

それを超えて、私はそのファサードパターンが好きだとは言えません。この可能性を排除するために、DBコンテキスト・コースDBSetに行くとどうなりますか?

context.Courses.Add(course); 
context.SaveChanges(); 
+0

@Steveに返信ありがとうございます。私はあなたのアドバイスをいくつか試しましたが運はありませんでした。( - ヌル入力可能なintではないので、その「CourseID = 0」部分を削除すると解決しません。 - Missing attribute DatabaseGeneratedOption.Identity is問題はありません - この冗長マッピングの削除も機能しません。実際には以前はありませんでしたが、EF6で問題の原因となった場合に備えて追加しました。 - 私は持っていません – Lucio

+0

Facadeは読み込みを複雑にしますが、 'context.Set(type).Add(entity)'や 'Database 'を呼び出すことでエンティティを別のオブジェクトに挿入することに気付きます。 Entry(entidad).State = EntityState.Added'は問題ではありません。実際にはリポジトリパターンはそうです。コントローラのこのような複数の挿入はすべて、彼は同じ例外ですが、EF4とEF5では正常に動作していました... – Lucio

関連する問題