[英]EF6 - error when insert entity with related entites only by navigation property
我需要在单个 DbSet.Add 调用中插入一个包含相关实体的实体。
Course 和 CourseProfesor 之间的一对多(CourseProfesor 是连接 Courses 和 Profesor 的实体)
实体:
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);
}
控制器:
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(entity) 执行一个 CreateCommand,它将依次调用
DbContext.Set(entity.GetType()).Add(entity)
我得到的例外:
对数据库的更改已成功提交,但在更新对象上下文时发生错误。 ObjectContext 可能处于不一致的状态。 内部异常消息:发生参照完整性约束冲突:关系一端的“Course.ID”属性值与另一端“CourseProfesor.CourseID”的属性值不匹配
如果我还不知道课程的 ID,如何分配 CourseProfesor.CourseID,因为两者都是新实体?
正如您在控制器代码中看到的,我曾经通过只设置导航属性来解决这个问题,EF 会相应地自动填充外键。
这很重要:这在 EF5 上运行良好,更新到 EF6 后出现该错误
任何线索为什么 EF6 抛出该异常而 EF5 没有? 以及如何在不必先创建 Course 然后创建 CourseProfesor 关系实体的情况下解决它?
有几点很突出:
course.Profesors.Add(new CourseProfesor() { Course = course, CourseID = 0, ProfesorID = profesorId, From = DateTime.Now, Role = ... });
使用导航属性时,我避免在实体中定义 FKs 字段,但如果您需要定义它们,则应避免设置它们。 仅使用导航属性。 设置 FK 可能会产生误导,因为如果您将这门课程与它的 CourseProfessors 一起传出去并使用它,则会有一个教授 ID 集,但没有可用的教授参考。
关于您的具体问题,可能的问题是上面设置的 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,但没有设置生成选项。 两个FK同样设置了Order=0和Order=1,不考虑PK就显得很奇怪了?
除此之外,我不能说我喜欢这种外观模式。 为了消除这种可能性,如果您转到 DB Context Courses DBSet 会发生什么?
context.Courses.Add(course);
context.SaveChanges();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.