这是表格

用户

UserId
UserName
Password
EmailAddress

还有代码..

public void ChangePassword(int userId, string password){
//code to update the password..
}

当前回答

Ladislav的答案更新为使用DbContext(在EF 4.1中引入):

public void ChangePassword(int userId, string password)
{
    var user = new User() { Id = userId, Password = password };
    using (var db = new MyEfContextName())
    {
        db.Users.Attach(user);
        db.Entry(user).Property(x => x.Password).IsModified = true;
        db.SaveChanges();
    }
}

其他回答

结合几项建议,我提出如下:

    async Task<bool> UpdateDbEntryAsync<T>(T entity, params Expression<Func<T, object>>[] properties) where T : class
    {
        try
        {
            var entry = db.Entry(entity);
            db.Set<T>().Attach(entity);
            foreach (var property in properties)
                entry.Property(property).IsModified = true;
            await db.SaveChangesAsync();
            return true;
        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.WriteLine("UpdateDbEntryAsync exception: " + ex.Message);
            return false;
        } 
    }

UpdateDbEntryAsync(dbc, d => d.Property1);//, d => d.Property2, d => d.Property3, etc. etc.);

或通过

await UpdateDbEntryAsync(dbc, d => d.Property1);

或通过

bool b = UpdateDbEntryAsync(dbc, d => d.Property1).Result;

在寻找这个问题的解决方案时,我在Patrick Desjardins的博客上找到了GONeale的答案:

public int Update(T entity, Expression<Func<T, object>>[] properties)
{
  DatabaseContext.Entry(entity).State = EntityState.Unchanged;
  foreach (var property in properties)
  {
    var propertyName = ExpressionHelper.GetExpressionText(property);
    DatabaseContext.Entry(entity).Property(propertyName).IsModified = true;
  }
  return DatabaseContext.SaveChangesWithoutValidation();
}

如你所见,它的第二个参数是a的表达式 函数。这将允许通过在Lambda中指定使用此方法 表示要更新哪个属性。”

...Update(Model, d=>d.Name);
//or
...Update(Model, d=>d.Name, d=>d.SecondProperty, d=>d.AndSoOn);

(这里也给出了一个类似的解决方案:https://stackoverflow.com/a/5749469/2115384)

我目前在自己的代码中使用的方法,扩展到处理类型ExpressionType.Convert的(Linq)表达式。这在我的例子中是必要的,例如Guid和其他对象属性。它们被“包装”在Convert()中,因此没有被System.Web.Mvc.ExpressionHelper.GetExpressionText处理。

public int Update(T entity, Expression<Func<T, object>>[] properties)
{
    DbEntityEntry<T> entry = dataContext.Entry(entity);
    entry.State = EntityState.Unchanged;
    foreach (var property in properties)
    {
        string propertyName = "";
        Expression bodyExpression = property.Body;
        if (bodyExpression.NodeType == ExpressionType.Convert && bodyExpression is UnaryExpression)
        {
            Expression operand = ((UnaryExpression)property.Body).Operand;
            propertyName = ((MemberExpression)operand).Member.Name;
        }
        else
        {
            propertyName = System.Web.Mvc.ExpressionHelper.GetExpressionText(property);
        }
        entry.Property(propertyName).IsModified = true;
    }

    dataContext.Configuration.ValidateOnSaveEnabled = false;
    return dataContext.SaveChanges();
}

您可以告诉EF哪些属性必须以这种方式更新:

public void ChangePassword(int userId, string password)
{
  var user = new User { Id = userId, Password = password };
  using (var context = new ObjectContext(ConnectionString))
  {
    var users = context.CreateObjectSet<User>();
    users.Attach(user);
    context.ObjectStateManager.GetObjectStateEntry(user)
      .SetModifiedProperty("Password");
    context.SaveChanges();
  }
}

在EntityFramework Core 2中。x不需要附加:

 // get a tracked entity
 var entity = context.User.Find(userId);
 entity.someProp = someValue;
 // other property changes might come here
 context.SaveChanges();

尝试在SQL Server和分析它:

exec sp_executesql N'SET NOCOUNT ON;
UPDATE [User] SET [someProp] = @p0
WHERE [UserId] = @p1;
SELECT @@ROWCOUNT;

',N'@p1 int,@p0 bit',@p1=1223424,@p0=1

Find确保已经加载的实体不会触发SELECT,并在需要时自动附加实体(来自文档):

查找具有给定主键值的实体。如果上下文正在跟踪具有给定主键值的实体,则立即返回该实体,而无需向数据库发出请求。否则,将向数据库查询具有给定主键值的实体,如果找到该实体,则将该实体附加到上下文并返回。如果没有找到实体,则返回null。

在实体框架核心中,Attach返回条目,所以你所需要的是:

var user = new User { Id = userId, Password = password };
db.Users.Attach(user).Property(x => x.Password).IsModified = true;
db.SaveChanges();