我有一对多的关系,我试图在"很多"上删除一组实例。但是,不断获得异常"不允许与处于“已删除”状态的实体添加关系"。这是实体框架6.1.1。
从教师到课程的关系是一对多的。这两个类定义为:
[Table("Course")]
public partial class Course {
public int Id { get; set; }
public int? TeacherId { get; set; }
public virtual Teacher Teacher { get; set; }
}
[Table("Teacher")]
public partial class Teacher
{
public Teacher()
{
Course = new HashSet<Course>();
}
public int Id { get; set; }
[Required]
[StringLength(50)]
public string TeacherName { get; set; }
public virtual ICollection<Course> Course { get; set; }
}
尝试删除课程的代码是导入的一部分:一组课程即将开始,应该从数据库中删除数据库中但不属于传入课程的课程。 (此外,应该创建属于传入集但不在数据库中的课程,但这似乎有效。)
var existingCourses = ctx.Courses.ToList();
var toCreate = incomingCourses.Where(x => !existingCourses.Contains(x)).ToList();
var coursesToDelete = existingCourses.Where(x => !incomingCourses.Contains(x)).ToList();
ctx.Courses.RemoveRange(coursesToDelete);
ctx.SaveChanges(); // The exception occurs here
将传入的课程集从XML文件解析为DTO。在将它们与现有课程进行比较之前,将它们放在以下列表中:
var incomingCourses = incomingDtos.Select(x => new Course
{
Teacher = new Teacher { TeacherName = x.TeacherNameFromXml }
}.ToList();
课程实体上还有其他属性可以识别课程,但我没有在这里显示,因为我认为它们无关紧要。
调试时,我注意到被删除的Courses的Teacher属性在调用RemoveRange()
之前是非空的,但之后为null ..所以似乎有某种类型的级联删除发生
我试图通过我的DbContext删除所有级联删除,并指定那里的关系。这没有任何改变。
public class MyDbContext : DbContext {
public MyDbContext() {}
public MyDbContext(string connectionString) {
Database.Connection.ConnectionString = connectionString;
}
public virtual DbSet<Teacher> Teacher { get; set; }
public virtual DbSet<Course> Courses { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
modelBuilder.Entity<Teacher>()
.HasMany(x => x.Course)
.WithOptional(x => x.Teacher)
.HasForeignKey(x => x.TeacherId)
.WillCascadeOnDelete(false);
}
}
答案 0 :(得分:1)
@LukasKabrt的评论指出了我正确的方向。我没有直接比较课程对象,而是将现有课程转换为DTO&#34;暂时&#34;在LINQ内部并比较DTO。现在,我可以从coursesToDelete
var coursesToDelete = (
from e in existing
let dto = new CourseDto(e)
where !incomingDtos.Contains(dto)
select e).ToList();