【问题标题】:Perform a Minimal Update in the Entity Framework在实体框架中执行最小更新
【发布时间】:2011-11-12 12:12:13
【问题描述】:

我想要做的是追加到记录的注释列。

我不想做的是获取整个记录,这非常重要。

这是工作的代码:

string AppendNote(int key, string note)
{
    using (MyEntities _Context = new MyEntities())
    {
        var _Record = _Context.Records
            .Where(x => x.Id == key)
            .Select(x => new Record { Id = x.Id, Notes = x.Notes })
            .First();
        _Record.Notes += note;
        _Context.SaveChanges();
    }
}

正确的方法是什么?

我意识到它与这个非常古老的问题非常相似:Update statement with Entity Framework 和这个相似但最终不同的问题:How to update a record without selecting that record again in ADO.NET Entity Framework? 但是,似乎仍然必须有办法。

【问题讨论】:

    标签: entity-framework


    【解决方案1】:

    至于 EF 中的 simple 最小更新,您可以通过将对象附加到上下文来完成,如下所示:

    string AppendNote(int key, string note)
    {
        using (MyEntities _Context = new MyEntities())
        {
            var _Record = new Record { Id = key };
            _Context.Entry(_Record).State = System.Data.EntityState.Unchanged;
            _Record.Notes = note; //a simple update
            _Context.SaveChanges();
        }
    }
    

    但是,您希望追加到当前值。由于匿名类型变量 _R,下面的代码有点混乱,但它应该只获取 Notes 列并附加到它:

    string AppendNote(int key, string note)
    {
        using (MyEntities _Context = new MyEntities())
        {
            var _R = _Context.Records
                .Select(x=>new {Id = x.Id, Notes=x.Notes})
                .Where(x=>x.Id == key)
                .First();
            var _Record = new Record { Id = _R.Id, Notes=_R.Notes };
            _Context.Entry(_Record).State = System.Data.EntityState.Unchanged;
            _Record.Notes+= note;
            _Context.SaveChanges();
        }
    }
    

    【讨论】:

    • 我只是知道这是可能的。
    【解决方案2】:

    这对于实体框架 afaik 是不可能的。您可以做的唯一优化是在加载记录实体时延迟加载所有导致“显着加载”的属性,并在不加载它们的情况下更新实体。

    如果您想避免一开始就加载实体,您可以使用ExecuteStoreQuery() 直接执行 SQL 以进行这些性能关键更新。

    最终,EF 是一种 ORM,它使 CRUD 变得更加容易,但使用这种抽象确实要付出性能代价。

    【讨论】:

    • 我希望你说的不对;使用 Linq to SQL 可以实现这一点也很烦人。但是它就是这样啊。感谢您对此的反馈。
    【解决方案3】:

    使用实体框架(或任何其他 ORM)执行此操作的最简单方法是为此使用存储过程 - 类似于:

    CREATE PROCEDURE dbo.UpdateNote(@Key INT, @Note VARCHAR(500))
    

    然后在那个存储过程中有一个简单的UPDATE 语句来完成这项工作。

    从实体框架中,您可以将该存储过程导入到您的对象上下文中,然后您可以将其作为对象上下文中的方法调用:

    string AppendNote(int key, string note)
    {
        using (MyEntities _Context = new MyEntities())
        {
            _Context.UpdateNote(key, note);
        }
    }
    

    并且只会执行这个单一的 SQL UPDATE 语句 - 该行不会不必要地传输到您的客户端。

    【讨论】:

      猜你喜欢
      • 2011-04-21
      • 2014-03-31
      • 1970-01-01
      • 1970-01-01
      • 2015-05-10
      • 2014-09-07
      • 1970-01-01
      • 2012-03-22
      • 1970-01-01
      相关资源
      最近更新 更多