Asp.net mvc 4 EF 5多对多在更新时正确创建领带,但在创建时不正确

Asp.net mvc 4 EF 5多对多在更新时正确创建领带,但在创建时不正确,asp.net-mvc-4,entity-framework-5,Asp.net Mvc 4,Entity Framework 5,我有一个使用MVC4和EF5的应用程序。我们有一个Test对象,它通过在两侧设置导航属性,将导航多对多连接到Grades。这将按预期创建一个中间多对多联接表 测试: public virtual ICollection<Grade> Grades { get; set; } 由于应用程序和业务规则的自定义设计,我为操作创建了一个自定义模型绑定器,它将属性request.Form.GetValues(Grades)作为string[]并使用AddRange()方法将适当的等级添加到t

我有一个使用MVC4和EF5的应用程序。我们有一个
Test
对象,它通过在两侧设置导航属性,将导航多对多连接到
Grades
。这将按预期创建一个中间多对多联接表

测试

public virtual ICollection<Grade> Grades { get; set; }
由于应用程序和业务规则的自定义设计,我为操作创建了一个自定义模型绑定器,它将属性
request.Form.GetValues(Grades)
作为
string[]
并使用
AddRange()
方法将适当的等级添加到
test.Grades
属性中,如下所示:

string[] values = request.Form.GetValues("Grades");
model.Grades.AddRange(context.Grades.Where(x => values.Contains(x.GradeLevel)).ToList();
这对于更新场景非常有效。但是,如果我的模型绑定器创建了一个新的
测试
,那么结果是EF将新等级添加到
等级
表中,然后使用新等级执行多对多联接,而不是使用现有等级

例如:

+-------------------+
|   Grades before   |
+--------+----------+
|GradeKey|GradeLevel|
+--------+----------+
|    1   |     K    |
|    2   |     1    |
|    3   |     2    |
|    4   |     3    |
+--------+----------+

Assume that during creation of the test only grades 1 and 2 were 
selected on the Add New Test screen    

+-------------------+
|    Grades after   |
+--------+----------+
|GradeKey|GradeLevel|
+--------+----------+
|    1   |     K    |
|    2   |     1    |
|    3   |     2    |
|    4   |     3    |
|    5   |     1    |
|    6   |     2    |
+--------+----------+
然后将测试加入新等级(图例5和6),而不是原始等级(图例2和3)

为什么新测试与现有
测试的这种行为不同

注意:我使用
Test Test=new Test()尝试了这两种方法testtest=newcontext.Tests.Add(newtest())

编辑:

模型活页夹:

public class TestModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        HttpRequestBase request = controllerContext.HttpContext.Request;
        Test model;
        using (DataContext context = new DataContext())
        {
            if (!string.IsNullOrWhiteSpace(request.Form.Get("TestKey")))
            {
                int testkey = int.Parse(request.Form.Get("TestKey"));
                model = context.Tests.Single(x => x.TestKey == testkey);
            }
            else model = context.Tests.Add(new Test());

            ...

            if (request.Form.Get("Grades") != null)
            {

                string[] values = request.Form.GetValues("Grades");
                model.Grades = context.Grades.Where(x => values.Contains(x.GradeLevel)).ToList();
            }

            ...

        }
        return model;
    }
}
控制器:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Test test)
{
    if (!ModelState.IsValid) return PartialView("_Create", test);
    //DataService.Context.Tests.Add(test); # Removed since model is added in model binder
    DataService.Context.SaveChanges();
    return RedirectToAction("Index");
}

编辑和创建场景的完整代码(与EF相关)是什么样子的-从加载/附加/创建<代码>模型
到<代码>保存更改
?添加了模型绑定代码和控制器操作。我想知道为什么会保存任何内容。您在模型绑定器中有一个单独的上下文实例(
使用(DataContext context=new DataContext())
),但不在此块中调用
SaveChanges
,而是稍后在操作中调用
DataService.context.SaveChanges()
。或者
newdatacontext()
是否以某种方式返回与
DataService.Context
相同的实例?否
DataService.Context
DataContext
的另一个实例。可能是
DataService.Context.Tests.Add(test)
允许它工作,因为在我上次运行应用程序时它仍然存在。我最初只使用模型活页夹中的
数据上下文
,这样我就可以提取正确的
等级
记录。模型活页夹还用于编辑和创建操作
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Test test)
{
    if (!ModelState.IsValid) return PartialView("_Create", test);
    //DataService.Context.Tests.Add(test); # Removed since model is added in model binder
    DataService.Context.SaveChanges();
    return RedirectToAction("Index");
}