为什么model = newModel不起作用,但model.title = newModel.title的作品?

问题描述:

我需要编辑数据库中的记录。我认为我做得不够好。我试过使代码缩短dev = newDev;,但它没有保存它。为什么model = newModel不起作用,但model.title = newModel.title的作品?

代码

[HttpPost] 
[ValidateInput(false)] 
public ActionResult Edit(Dev newDev) 
{ 
    try 
    { 
     if (TryUpdateModel(newDev) == true) 
     { 
      var dev = _db.Devs.Where(x => x.ID == newDev.ID).Single(); 
      dev.Title = newDev.Title; 
      dev.Body = newDev.Body; 
      dev.Tags = newDev.Tags; 
      dev.Image1 = newDev.Image1; 
      dev.Image2 = newDev.Image2; 
      dev.Image3 = newDev.Image3; 
      dev.Image4 = newDev.Image4; 
      _db.SubmitChanges(); 
      return RedirectToAction(""); 
     } 
     else 
     { 
      return Content("Fail."); 
     } 
    } 
    catch 
    { 
     return View(); 
    } 
} 

你能在这里帮我优化我的代码?

+0

你想完成什么? – drdwilcox

+0

请提供更多详细信息,并给我们一个完整的工作代码示例,包括保存到您的上下文中。例如,'newModel'来自哪里?你在使用实体框架吗? –

+0

model = newModel肯定有效。但是也许你正在用一种方法来执行这个操作,并期望这种改变也会出现在调用改变的方法中。在这种情况下,它将无法工作。如果你想能够做到这一点,你必须通过引用传递变量(void methodName(ref Model model))。 –

如果你正在使用实体框架(它看起来像?),那么你不能以这种方式更新实体。

实体框架使用更改跟踪来了解实体发生了什么变化。为此,它会保存从该上下文加载的特定实例的列表,以及它们的初始状态,以便可以在调用上下文中的SaveChanges之前检测对这些实例所做的更改。

当您直接指定给引用类型时,您只是重新设置引用。您不会更改初始对象实例。现有对该实例的引用(如实体框架在内部保持以跟踪更改的实例)不会更改,并且最终会指向不同的对象实例。

所以,只需使用你现在拥有的代码即可。这是盲目更新每个领域的唯一方法。如果没有更新,实体框架的更改跟踪应该会导致SaveChanges无法执行任何操作。如果更新了某些内容,它将执行相应的SQL以将更改保存到数据库中。

您需要阅读.NET使用的内存模型。设置dev = newDev将改变dev变量的值,但变量具有局部范围。它不会更改引用同一对象的其他变量的值。

在这种情况下,你拉从dev上下文可能是跟踪它拉出,并给你的dev的,因此,如果您更改其属性和调用的SaveChanges那么它会知道哪些值变化。

如果你只是想,而无需手动编写一行代码为每个属性的所有值从一个对象复制到另一个,你应该能够use a tool like AutoMapper自动所有类似命名的属性从一个地图反对另一个。

+0

对于自动映射器建议+1。这将使您可以减少必须编写的代码数量,以将所有字段复制到数据库跟踪的对象实例。 –

如果还是不行,那么:1。 开发是引用类型 2.开发一提的是被更改为指向另一个对象(newDev)

这意味着,你是已经在背景之外使用了一个对象。为了能够更新该对象,您首先需要以某种方式将该对象附加到上下文,并使上下文知道它是其中某个现有实体的更新对象。

希望这会有所帮助。