这是表格

用户

UserId
UserName
Password
EmailAddress

还有代码..

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

当前回答

public void ChangePassword(int userId, string password)
{
  var user = new User{ Id = userId, Password = password };
  using (var db = new DbContextName())
  {
    db.Entry(user).State = EntityState.Added;
    db.SaveChanges();
  }
}

其他回答

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

var user = new User { Id = userId, Password = password };
db.Users.Attach(user).Property(x => x.Password).IsModified = true;
db.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。

您可以告诉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();
  }
}

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();
    }
}

新的EF Core 7原生功能- ExecuteUpdate:

终于!经过漫长的等待,EF Core 7.0现在有一个本地支持的方式来运行UPDATE(也删除)语句,同时还允许您使用任意的LINQ查询(。其中(u =>…)),而无需首先从数据库中检索相关实体:新的内置方法称为ExecuteUpdate -参见“EF Core 7.0有什么新功能?”

ExecuteUpdate正是针对这些场景的,它可以对任何IQueryable实例进行操作,并允许您在任意数量的行上更新特定的列,同时始终在幕后发出单个update语句,使其尽可能高效。

用法:

让我们以OP为例——即更新特定用户的密码列:

dbContext.Users
    .Where(u => u.Id == someId)
    .ExecuteUpdate(b =>
        b.SetProperty(u => u.Password, "NewPassword")
    );

如您所见,调用ExecuteUpdate需要调用SetProperty方法,以指定要更新的属性,以及要给它赋什么新值。

EF Core会将此转换为以下UPDATE语句:

UPDATE [u]
    SET [u].[Password] = "NewPassword"
FROM [Users] AS [u]
WHERE [u].[Id] = someId

另外,ExecuteDelete用于删除行:

ExecuteUpdate还有一个名为ExecuteDelete的对应程序,顾名思义,它可用于一次删除单个或多个行,而无需首先获取它们。

用法:

// Delete users that haven't been active in 2022:
dbContext.Users
    .Where(u => u.LastActiveAt.Year < 2022)
    .ExecuteDelete();

类似于ExecuteUpdate, ExecuteDelete将在幕后生成DELETE SQL语句——在本例中,是以下语句:

DELETE FROM [u]
FROM [Users] AS [u]
WHERE DATEPART(year, [u].[LastActiveAt]) < 2022

另注:

Keep in mind that both ExecuteUpdate and ExecuteDelete are "terminating", meaning that the update/delete operation will take place as soon as you call the method. You're not supposed to call dbContext.SaveChanges() afterwards. If you're curious about the SetProperty method, and you're confused as to why ExectueUpdate doesn't instead receive a member initialization expression (e.g. .ExecuteUpdate(new User { Email = "..." }), then refer to this comment (and the surrounding ones) on the GitHub issue for this feature. Furthermore, if you're curious about the rationale behind the naming, and why the prefix Execute was picked (there were also other candidates), refer to this comment, and the preceding (rather long) conversation. Both methods also have async equivalents, named ExecuteUpdateAsync, and ExecuteDeleteAsync respectively.