正确的方法使用编辑数据模型第一种方法与实体框架的MVC 3的实体? [英] Proper way to Edit an entity in MVC 3 with the Entity Framework using Data Model First approach?

查看:106
本文介绍了正确的方法使用编辑数据模型第一种方法与实体框架的MVC 3的实体?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一个大多数我看到的例子,现在要么使用code第一种方法或使用MVC和实体框架的旧版本。

假设我有一个电影更新和我得到的编辑视图,在编辑方法与邮政动词,什么是更新电影的正确方法?下面的第一个编辑方法让我来编辑视图与电影填充值,第二个是一个我想用更新,我已经尝试了一些东西,但没有更新数据。

 公众的ActionResult编辑(INT ID)
        {
            变种电影=(从_db.Movies1米
                         其中,m.Id == ID
                         选择M)。首先();            返回查看(电影);
        }    [HttpPost]
    公众的ActionResult编辑(动画电影)
    {
        尝试
        {
            // TODO:添加更新逻辑这里           //我需要什么叫更新实体?            _db.SaveChanges();
            返回RedirectToAction(「指数」);
        }
        抓住
        {
            返回查看();
        }
    }


解决方案

假设 _db 的ObjectContext 导出你有两个选择:


  • 更改实体的状态修改

    _db.Movies1.Attach(电影);
    _db.ObjectStateManager.ChangeObjectState(电影,EntityState.Modified);
    _db.SaveChanges();

    此标记的所有电影的特性的修改,将发送一个UPDATE语句,其中包括所有列值的数据库,无论在值真的变了还是不行。


  • 刷新从数据库中原来的实体更改应用到它:

    VAR originalMovie =(从_db.Movies1米
                         其中,m.Id == movie.Id
                         选择M)。首先();
    //你其实并不需要分配给一个变​​量。
    //加载实体到上下文是足够的。_db.Movies1.ApplyCurrentValues​​(电影);
    _db.SaveChanges();

    ApplyCurrentValues​​ 将迎来只有那些属性,修改它确实改变相比原来的,哪些将被发送到数据库的UPDATE语句只包含更改的列值。因此,UPDATE语句可能比第一个例子较小,但你必须付出的代价,重新载入数据库原始的实体。


修改

如何在第二code例如工作?


  • 在运行使用上下文的查询( _db )实体框架不会只从数据库中检索实体,并将其分配到的左侧查询( originalMovie ),但它实际上在内部存储第二参考。你可以认为这个内部语境缓存作为键 - 值对的字典 - 关键是实体主键和值是实体本身,相同的对象 originalMovie 引用。


  • ApplyCurrentValues​​(电影)查找本单位在上下文的内部词典:它需要的关键属性值编号电影传递的,从(分离)<$传入的搜索与内部字典中键的实体,然后拷贝财产属性C $ C>电影到内部(附加)实体相同的密钥。 EF的变动追踪机制,标志着属性修改这实际上是不同的创建后,相应的UPDATE语句。


由于这种内部参考原始的实体,你并不需要持有自己参考的:这就是为什么 originalEntity 未在code使用的原因。您可以实际上除去给局部变量干脆。

如果您禁用更改跟踪,当你加载原始实体的例子是行不通的 - 通过设置,例如 _db.Movies1.MergeOption = MergeOption.NoTracking; 。这个例子依赖于启用更改跟踪(这是当实体从数据库中加载默认设置)。

我不能说这两个例子具有更好的性能。这可能取决于像实体大小的详细信息,属性数已改变等。

这是值得大家注意不过,如果相关的实体参与这两种方法不起作用(例如电影指的是一类实体),如果关系或相关实体本身可能已被改变。设置状态修改,并使用 ApplyCurrentValues​​ 两者仅影响标量和电影的复杂属性但不能导航属性。

A majority of the examples I see now are either using the Code First Approach or using an older version of MVC and the Entity Framework.

Assume I have a movie to update and I get to the Edit View, in the Edit method with the Post verb, what is the proper way to update a Movie? The first Edit Method below gets me to the Edit View with the populated Movie values and the second one is the one I want to use to update, I have tried some things, but nothing updates the data.

 public ActionResult Edit(int id)
        {
            var movie = (from m in _db.Movies1
                         where m.Id == id
                         select m).First();

            return View(movie);
        }

    [HttpPost]
    public ActionResult Edit(Movie movie)
    {
        try
        {
            // TODO: Add update logic here

           //What do I need to call to update the entity?

            _db.SaveChanges();
            return RedirectToAction("Index");
        }
        catch
        {
            return View();
        }
    }

解决方案

Assuming that _db is derived from ObjectContext you have two options:

  • Change the state of the entity to Modified:

    _db.Movies1.Attach(movie);
    _db.ObjectStateManager.ChangeObjectState(movie, EntityState.Modified);
    _db.SaveChanges();
    

    This marks all properties of movie as modified and will send an UPDATE statement to the database which includes all column values, no matter if the values really changed or not.

  • Reload the original entity from the database and apply the changes to it:

    var originalMovie = (from m in _db.Movies1
                         where m.Id == movie.Id
                         select m).First();
    // You actually don't need to assign to a variable.
    // Loading the entity into the context is sufficient.
    
    _db.Movies1.ApplyCurrentValues(movie);
    _db.SaveChanges();
    

    ApplyCurrentValues will mark only those properties as modified which really did change compared to the original and the UPDATE statement which will be sent to the database only includes the changed column values. So, the UPDATE statement is potentially smaller than in the first example but you have to pay the price to reload the original entity from the database.

Edit

How does the second code example work?

  • When you run a query using the context (_db) Entity Framework does not only retrieve the entity from the database and assign it to the left side of the query (originalMovie) but it actually stores a second reference internally. You can think of this internal context "cache" as a dictionary of key-value pairs - the key is the entity primary key and the value is the entity itself, the same object as originalMovie refers to.

  • ApplyCurrentValues(movie) looks up this entity in the context's internal dictionary: It takes the key property value Id of the passed in movie, searches for an entity with that key in the internal dictionary and then copies property by property from the passed in ("detached") movie to the internal ("attached") entity with the same key. EF's change tracking mechanism marks the properties as Modified which were actually different to create later the appropriate UPDATE statement.

Because of this internal reference to the original entity you do not need to hold your own reference: That's the reason why originalEntity is not used in the code. You can in fact remove the assignment to the local variable altogether.

The example would not work if you disable change tracking when you load the original entity - for example by setting _db.Movies1.MergeOption = MergeOption.NoTracking;. The example relies on enabled change tracking (which is the default setting when entities are loaded from the database).

I cannot say which of the two examples has better performance. That might depend on details like size of the entities, number of properties which have been changed, etc.

It's worth to note though that both approaches do not work if related entities are involved (for example movie refers to a category entity) and if the relationship or the related entity itself could have been changed. Setting the state to Modified and using ApplyCurrentValues both affect only scalar and complex properties of movie but not navigation properties.

这篇关于正确的方法使用编辑数据模型第一种方法与实体框架的MVC 3的实体?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆