我需要在一个DbSet.Add调用中插入一个包含相关实体的实体。
课程与CourseProfesor之间的一对多(CourseProfesor是连接课程和教授的实体)
实体:
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可能处于不一致状态。内部异常消息:发生了参照完整性约束违规:&#39; Course.ID&#39;的属性值。在一段关系的一端与&#39; CourseProfesor.CourseID&#39;的财产价值不匹配。在另一端
如果我还不知道课程的ID,如何分配CourseProfesor.CourseID,因为两者都是新实体?
正如您在控制器代码中看到的那样,我曾经通过设置导航属性来解决这个问题,EF会相应地自动填充外键。
这很重要:这在EF5上工作正常,我在更新到EF6后出现了错误
任何线索为什么EF6抛出异常而EF5没有?以及如何解决它而无需先创建课程,然后再创建CourseProfesor关系实体?
答案 0 :(得分:0)
有几件事情很突出:
course.Profesors.Add(new CourseProfesor() { Course = course, CourseID = 0, ProfesorID = profesorId, From = DateTime.Now, Role = ... });
使用导航属性时,我避免在实体中定义FKs字段,但如果需要定义它们,则应避免设置它们。仅使用导航属性。设置FK可能会产生误导,因为如果您要将此课程与其课程教授一起使用并使用它,则会有一个教授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();