使用枚举更新实体不首先删除ef代码中的旧条目

时间:2015-02-28 21:48:09

标签: c# asp.net-mvc entity-framework

我有一个教师实体没有更新我的瑜伽课程'表格正确,它正在为瑜伽课程编写新的价值观。但不能删除/修改旧值。为了解决这个问题,我需要重新构建我的控制器以修改旧值,还是需要修改我的存储库以在插入新值之前删除旧值?

public class Teacher
{
   // other members...
   public virtual ICollection<YogaClass> YogaClasses { get; set; } 
}

YogaClass对象在这里有一个枚举。

public class YogaClass
{
    public int YogaClassId { get; set; }
    public YogaStyle YogaStyle { get; set;}
}

YogaStyle就在这里。

public enum YogaStyle
{
    [Display(Name = "Beginner Anusara")]
    BeginnerAnusara,
    [Display(Name = "Intermediate Anusara")]
    IntermediateAnusara,
    // more members here...
}

如果教师已经添加了YogaClasses(多选下拉列表),它将如下所示。

enter image description here

现在让我们说老师进去并取消选择她之前的一些选择并添加新选项。当我更新时,实体框架不会删除/删除/修改以前的条目,它只会写出这样的新条目。您可以看到老师删除了1,4,6并添加了52,53,54,55。

enter image description here

在我的控制器中,在我发布UpdateOrInsert()&#39;之前在我的存储库中,我只是设置了老师在这里选择的所有类

 public ActionResult Edit(EditTeacherViewModel viewModel)
 {  
     // other code here...
     teacher.YogaClasses = GetSelectedClasses(viewModel);
     teacherRepository.InsertOrUpdate(teacher);
 }

这是GetSelectedClasses方法

 private ICollection<YogaClass> GetSelectedClasses(EditTeacherViewModel viewModel)
    {
        ICollection<YogaClass> classes = new Collection<YogaClass>();
        int[] selectedClasses = viewModel.SelectedYogaStyles;
        foreach (int selectedClass in selectedClasses)
        {
            YogaClass yogaClass = new YogaClass();
            yogaClass.YogaStyle = (YogaStyle)selectedClass;
            classes.Add(yogaClass);
        }
        return classes;
    }

这是我的&#39; UpdateOrInsert()&#39;来自我的回购。

public void InsertOrUpdate(Teacher teacher)
    {
        if (teacher.TeacherId == default(int))
        {
            // New entity
            context.Teachers.Add(teacher);
        }
        else
        {
            // Existing entity
            context.Entry(teacher).State = EntityState.Modified;
        }
    }

2 个答案:

答案 0 :(得分:1)

您需要将旧条目设置为EntityState.Deleted。我会在服务器端更明确,例如删除ActionResult。这应该是更可测试的。您还想删除YogaClass实体,以便您可能有一个控制器来执行此操作吗?没有理由你不能通过更新/插入教师ActionResult来调用它。

更新reposne to question: 您需要取消您删除YogaClass记录而不是教师记录。例如:

var teacher = new Teacher();
teacher.id = 0;
teacher.Yogaclasses = new List<YogaClass>();
context.Teachers.Add(teacher);
context.SaveChanges

我们知道有一位没有瑜伽课程的老师。在db中,Teacher表中将有一行,其id为1。

您添加了YogaClass条目。并将它们与教师联系起来。

var yogaClass = new YogaClass();
yogaClass.yogastyle = 1;
yogaClass.teacherId = 1: 

保存更改等。

当您从数据库中检索ID为1的教师时,一旦详细信息全部保存到数据库,上下文将为您填充YogaClasses。让我们说你为10个YogaClasses做了这个,他们有Ids 1到10;

如果我然后向客户证明这个列表,并且当我收到教师对象回到我的更新方法时他们删除了Id 1和2的YogaClasses,我可以:

从上下文中检索当前数据库对象(列表中仍有10个YogaClass项); 我可以在上下文objext中迭代YogaClass项目并检查ViewModel对象是否具有相同的记录。对于ViewModel上不存在但在上下文对象上存在的任何项目,需要将其删除。

我知道我有两个需要删除的YogaClass条目(id 1和2)。这是一个单独的担忧(想想SOLID总是!!)。我可以在我的存储库中公开一个DeleteYogaClass(YogaClass yogaClass)方法或者DeleteYogaClasses(IEnumerable yogaClasses)

单个YogaClass:

    try
    {
        context.YogaClasses.Remove(yogaClass);
        context.SaveChanges();
    }
    catch (OptimisticConcurrencyException ex)
    {
        throw new InvalidOperationException(string.Format(
            "The YogaClass with an ID of '{0}' could not be deleted etc etc";
    }

对于多个类foreach并将all设置为已删除。

答案 1 :(得分:0)

嗯说@Luthervd,在发布更新的条目之前先清除旧条目。