0

我在修改其中一个实体时更新两个实体之间的关系时遇到问题。请注意,我正在使用实体框架4.0。实体框架 - 不更新的关系

非常基本上,Category需要属于一个Department(一个Department对许多Categories)。

我实现直接下到Category模式:

public void Save() 
{ 
    using (var db = new MyDatabase()) 
    { 
     if (this.id > 0) 
     { 
      db.Categories.Attach(this); 
      db.ObjectStateManager.ChangeObjectState(this, EntityState.Modified); 
     } 
     else 
     { 
      db.Categories.AddObject(this); 
     } 

     db.SaveChanges(); 
    } 
} 

public int DepartmentID 
{ 
    get 
    { 
     if (this.DepartmentReference.EntityKey == null) return 0; 
     else return (int)this.DepartmentReference 
      .EntityKey.EntityKeyValues[0].Value; 
    } 
    set 
    { 
     this.DepartmentReference.EntityKey 
      = new EntityKey("MyDatabase.Departments", "Id", value); 
    } 
} 

创建对象的工作没有问题,这是ONY当我尝试保存时发生的问题进行修改的项目(所以问题在于该if (this.id > 0)内块)。

我知道EntityState.Modified只适用于标量值。上面的代码片段是稍旧的版本。我已经尝试过以多种方式解决这个问题,但没有一个解决了这个问题。

我在Stackoverflow上找到了很多解决方案,但都没有工作。请参阅以下我以前尝试的片段。

我检查了调试中的值,当前项目的DepartmentDepartmentID字段正确保存更改的值。在附着之前,在附着之后,一路通过。但实体框架忽略了这些更改,同时仍然正确地执行标量值调整。

我错过了什么?如果有人能指出我正确的方向?

我尝试的东西还包括:

//First try 
if (this.id > 0) 
{ 
    var department = db.Departments.Single(x => x.Id == this.DepartmentID); 

    db.Categories.Attach(this); 

    this.Department = department; 

    db.ObjectStateManager.ChangeObjectState(this, EntityState.Modified); 
} 

//Second try 
if (this.id > 0) 
{ 
    db.Categories.Attach(this); 
    db.Departments.Attach(this.Department); 

    db.ObjectStateManager.ChangeObjectState(this, EntityState.Modified); 
} 

//Third try 
if (this.id > 0) 
{ 
    var department = db.Departments.Single(x => x.Id == this.DepartmentID); 

    db.Categories.Attach(this); 

    this.DepartmentID = department.Id; 

    db.ObjectStateManager.ChangeObjectState(this, EntityState.Modified); 
} 

//Fourth try 
if (this.id > 0) 
{ 
    var departmentID = this.DepartmentID; 

    db.Categories.Attach(this); 

    this.Department = db.Departments.Single(x => x.Id == departmentID); 

    db.ObjectStateManager.ChangeObjectState(this, EntityState.Modified); 
} 

更新

按照要求,这里是如何的.Save()方法被调用。请注意,实际的网页表格已经使用TextBoxFor()等构建,因此模型绑定没问题。这种完全相同的方法也用于类别的创建,这些类别按预期工作。

public JsonResult SaveCategory(Category category) 
    { 
     try 
     { 
      category.Save(); 

      return Json(category.toJson(), JsonRequestBehavior.AllowGet); 
     } 
     catch (Exception ex) 
     { 
      return Json("ERROR", JsonRequestBehavior.AllowGet); 
     } 
    } 
+1

请您分享调用Save()方法的代码吗? –

+0

它只不过是模型绑定(通过MVC),然后调用Save()。但为了清晰起见,我会添加它。更新:我添加了它。 – Flater

+0

他们这样做的方式有时可能会很棘手,看看这是否有助于你:http://stackoverflow.com/questions/15177372/entity-framework-modify-detached-object –

回答

0

我设法找到问题。这不是一件容易的事。

我注意到我的大多数关系都为'child'实体创建了一个Scalar值。 (例如,Category应该自动收到标量值DepartmentID)。但事实并非如此。

以下是问题:如果您在EF中创建关联,则会出现一个窗口,要求您选择要关联哪两个实体。 孩子(类别,一)需要在正确的领域,而家长(部门,很多)需要在左边。 菜单可以让你把它们放在任何一边,没有什么能阻止你这样做。但是只有当你输入数据一个< - >许多你会得到标量值。不是当你把它像很多< - >一个>即使这应该是字面上相同的事情。

我说得对,这是一个错误吗?

我的原始片段,只有.Attach()EntityState.Modified现在按预期工作。

我只能在2天内将此答案标记为正确,但您可以将此问题视为已关闭。

0

您必须在修改实体后调用db.SaveChanges()

+0

它在那里,但只在'if else'块之后。我没有将它包含在块中,因为无论是否创建或更新,都需要调用它。 – Flater

+0

您可以添加部门和类别模式吗? –

+0

它们是由实体框架创建的,我使用的是模型的第一种方法('从模型生成数据库')。您看到的片段是我为扩展实体而创建的部分“类别”类的一部分。除了我所添加的东西外,其他都是由EF生成的它是什么syou特别想知道的实体? **编辑:**这不是一个独特的问题。数据模型中的所有类似关系都有相同的问题。我假设EF有一些功能我没有正确使用,因为我基本上使用了相同的Save函数。 – Flater