C# 编辑子实体不会';不要从表中删除旧的行,它总是在实体框架ASP.NETMVC中添加新的行
我有一个教师实体,它有一个叫做瑜伽课的子实体。当我修改教师的瑜伽课程列表并保存时,entity framework会将新的瑜伽课程行添加到表“YogaClass”中,但不会删除或编辑旧的行。所以我只剩下两倍的数据。我的repo中的“context.SaveChanges()”不应该聪明到知道删除已删除的类并添加新类(编辑),而不仅仅是添加新类吗 在我的控制器中,我有类似这样的东西供教师编辑C# 编辑子实体不会';不要从表中删除旧的行,它总是在实体框架ASP.NETMVC中添加新的行,c#,asp.net-mvc,entity-framework,C#,Asp.net Mvc,Entity Framework,我有一个教师实体,它有一个叫做瑜伽课的子实体。当我修改教师的瑜伽课程列表并保存时,entity framework会将新的瑜伽课程行添加到表“YogaClass”中,但不会删除或编辑旧的行。所以我只剩下两倍的数据。我的repo中的“context.SaveChanges()”不应该聪明到知道删除已删除的类并添加新类(编辑),而不仅仅是添加新类吗 在我的控制器中,我有类似这样的东西供教师编辑 string userId = User.Identity.GetUserId(); Teacher te
string userId = User.Identity.GetUserId();
Teacher teacher = teacherRepository.Find(userId);
//other code left out here
teacher.YogaClasses = GetSelectedClasses(Request.Form[2]);
// other stuff here
teacherRepository.Save();
在我的静谧中,我有这个
public void Save()
{
context.SaveChanges();
}
这是我的老师和瑜伽课
public class Teacher
{
public int TeacherId { get; set; }
public virtual ICollection<YogaClass> YogaClasses { get; set; }
}
public class YogaClass
{
public int YogaClassId { get; set; }
[Index]
[Required]
public int TeacherRefId { get; set; }
[ForeignKey("TeacherRefId")]
public virtual Teacher Teacher { get; set; }
}
公共课堂教师
{
public int TeacherId{get;set;}
公共虚拟ICollection数据库{get;set;}
}
公营酸奶班
{
公共类{get;set;}
[索引]
[必需]
公共int-TeacherRefId{get;set;}
[外键(“教师识别”)]
公共虚拟教师{get;set;}
}
您需要使用上下文的附加
方法,传入现有的教师
对象,然后进行更改并调用保存更改
方法。从您的代码中不清楚您的上下文是什么,所以很难给出有效的代码。是一个解释如何添加/修改的链接
你说你需要修改瑜珈课,因此我假设教师对象已经有一些瑜珈课条目,你想更新其中的一些条目。您需要做的是,有一个需要修改的yogaClass ID列表,然后在该ID列表上迭代,在该迭代循环中找到现有的yogaClass并将其附加到上下文中,修改它,然后调用save changes(最好在所有更改都完成时调用,这样不会影响性能)
这里有一个suodocode
UpdateTeacher(int teacherId)
{
var teacher = teacherRepository.Find(teacherId);
UpdateYoga(teacher);
}
private void UpdateYoga(Teacher teacher)
{
foreach(var yoga in teacher.YogaClasses)
{
db.Context.Attach(yoga);
yoga.YogaStyle = whatEverValue;
}
db.context.SaveChanges();
}
这里的问题是,在设置
teacher.YogaClasses
时,尚未加载关系。因此,当您设置teacher.YogaClasses
时,它假定将添加新的关系。(在这种情况下,懒散加载仍然有点晚)。解决方案是,首先确保加载所有关系(使用Include
或一些伪访问来触发懒散加载),然后正常设置新值:
//fake access to trigger lazy loading (of course this works only if
//lazy loading is enabled)
var someClasses = teacher.YogaClasses;
teacher.YogaClasses = GetSelectedClasses(Request.Form[2]);
您还可以通过foreach循环清除旧类并添加新类:
teacher.YogaClasses.Clear();
foreach(var c in GetSelectedClasses(Request.Form[2])){
teacher.YogaClasses.Add(c);
}
我有一个肮脏的解决方案,但它似乎不是最好的 在我保存repo中的教师上下文之前,我可以称之为
public void DeleteYogaClasses(Teacher teacher)
{
foreach (var yogaClass in teacher.YogaClasses.ToList())
{
context.Entry(yogaClass).State = EntityState.Deleted;
}
context.SaveChanges();
}
我尝试了“teacher.yogalass.Clear()”这种方法,但它并没有删除“yogalass”中的行,只是将“teacher\u TeacherId”置空column@user1186050那么第一种方法呢?不,它和你的另一种解决方案是一样的。它会使teacher\u teacherId列为空,并且表中的行仍然存在。@user1186050我想您的
teacher\u teacherId
列不是必需的(允许为空)。应将其标记为不允许为空。在这种情况下,EF将自动级联删除瑜珈类。此列由EF自动生成,因此我必须在代码第一个实体“YogaClass”中更改什么,以使其不可为空?请您在此处进一步说明。我是否需要传递一个要附加的教师对象或一个瑜珈课堂到教师上下文?即使使用这个解决方案,我刚刚尝试过,没有行被删除,只是添加到瑜珈课堂表中,我已经尝试用一些例子来解释它,请查看更新的答案,并让我知道这是否在某些方面有所帮助或需要改进。我想你在这里感到困惑。我的上下文是一个教师实体。不能将瑜伽课附加到教师上下文。您只能将yogaclass附加到yogaclass上下文。请发布GetSelectedClasses()方法