实体框架3.5 - 如何在不首先从数据库加载行的情况下更新行

时间:2011-07-31 13:17:59

标签: c# sql-server entity-framework

这是我目前更新数据库中字段的代码

private void SaveUser(User user)
{
   USER UserObj = _db.USERs.First(i => i.USER_ID == user.USER_ID);
   UserObj.NAME = user.NAME;
   _db.SaveChanges();
}

这很好用。但是,我想改变两件事

1)我可以先跳过从DB加载行吗?即这一行USER UserObj = _db.USERs.First(i => i.USER_ID == user.USER_ID);

2)如果要更新20个字段,如何一次设置所有字段?或者我必须自己编写所有20个作业?

由于

4 个答案:

答案 0 :(得分:5)

修改 - 为EFv1修改过的示例 - 它可以回答您的问题:

您正在寻找:

private void SaveUser(User user)
{
    // Attach dummy entity - it must have only primary key property and EntityKey 
    // property assigned
    _db.USERs.Attach(new User() { ... });
    // Apply current values to dummy entity - this will mark the entity as modified
    // and it will also mark all properties (except key and store generated) as modified
    _db.ApplyPropertyChanges("UserSetName", user);
    _db.SaveChanges();
}

EntityObject s(今天大部分已过时)和POCO(仅EFv4)之间存在一些差异,如果POCO标记为已修改但EntityObject未标记为已更改,则POCO会更新。仅当属性与其原始状态不同或者在ObjectStateEntry中手动将属性设置为已修改时,它才会更新。

有选择地定义必须更新哪些属性与手动分配它们相同:

private void SaveUser(User user)
{
    _db.USERs.Attach(user);
    ObjectStateEntry entry = _db.ObjectStateManager.GetObjectStateEntry(user);
    entry.SetModifiedProperty("PropertyName");
    // set other properties
    _db.SaveChanges();
}

顺便说一下。你听说过命名惯例吗?

答案 1 :(得分:0)

如果要更新已存在的用户,则应该已经在使用从数据库中提取的用户。例如,如果您有一个业务规则,用户可以在页面上更新其名字,则应首先:按用户ID获取用户,像您一样执行更新,然后将用户保存回来。您还可以获得对对象进行验证的好处,并且获取它的成本并不高。

这不是你的问题,但我认为值得指出(从数据库中提取是正常的,也可以)。如果你不想从db中提取,我相信你可以编写和临时查询,但可能不是通过实体框架。对于第2部分,我没有看到任何方法更新20个字段而不告诉EF这20个字段是什么。它需要知道在某种程度上要更新的内容。

我知道这个答案的某些部分可能不尽如人意,但总体而言我建议使用框架而不是反对它。

答案 2 :(得分:0)

  1. 如果您想在不首先从数据库加载内容的情况下更新内容,则必须创建存储过程并将其映射到您的上下文(或使用与实体框架完全不同的内容)。

    < / LI>
  2. 如果从数据库中检索对象并在调用SaveChanges()之前更新20个字段,则所有更改将在一个事务操作中刷新到数据库,因此它们将基本上是“一次性”更新。

答案 3 :(得分:0)

对于问题的第一部分检查this,它会执行您需要的操作,但您必须知道要更新的实体的主键

对于第二部分,您必须告诉您的上下文您将更新哪个实体以及将为哪些字段(属性)分配新值,但最有趣的是您只需一次点击数据库即可通过调用来运行更新SaveChanges()方法