这是表格
用户
UserId
UserName
Password
EmailAddress
还有代码..
public void ChangePassword(int userId, string password){
//code to update the password..
}
这是表格
用户
UserId
UserName
Password
EmailAddress
还有代码..
public void ChangePassword(int userId, string password){
//code to update the password..
}
当前回答
新的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.
其他回答
你基本上有两个选择:
一直用EF的方法,在这种情况下,你会 根据提供的userId加载对象——整个对象都会被加载 更新密码字段 使用上下文的.SaveChanges()方法将对象保存回来
在这种情况下,具体如何处理就取决于EF了。我刚刚测试了这个,在这种情况下,我只改变一个对象的一个字段,EF创建的几乎是你手动创建的,太像:
`UPDATE dbo.Users SET Password = @Password WHERE UserId = @UserId`
因此,EF足够聪明,可以找出哪些列确实发生了更改,并且它将创建一个T-SQL语句来处理实际上必要的更新。
你在T-SQL代码中定义了一个完全满足你需要的存储过程(只更新给定UserId的Password列,其他什么都不做——基本上执行update dbo。Users SET Password = @Password WHERE UserId = @UserId),然后在EF模型中为该存储过程创建一个函数导入,并且调用这个函数,而不是执行上面概述的步骤
您可以告诉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();
}
}
实体框架跟踪您通过DbContext从数据库查询的对象的更改。例如,如果你的DbContext实例名是DbContext
public void ChangePassword(int userId, string password){
var user = dbContext.Users.FirstOrDefault(u=>u.UserId == userId);
user.password = password;
dbContext.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.
我使用valueinjector nuget注入绑定模型到数据库实体使用如下:
public async Task<IHttpActionResult> Add(CustomBindingModel model)
{
var entity= await db.MyEntities.FindAsync(model.Id);
if (entity== null) return NotFound();
entity.InjectFrom<NoNullsInjection>(model);
await db.SaveChangesAsync();
return Ok();
}
注意使用自定义约定,如果属性在服务器上为空,则不更新属性。
ValueInjecter v3 +
public class NoNullsInjection : LoopInjection
{
protected override void SetValue(object source, object target, PropertyInfo sp, PropertyInfo tp)
{
if (sp.GetValue(source) == null) return;
base.SetValue(source, target, sp, tp);
}
}
用法:
target.InjectFrom<NoNullsInjection>(source);
值注入器V2
查找这个答案
警告
您将不知道该属性是被故意清除为null还是它只是没有任何值。换句话说,属性值只能被替换为另一个值,而不能被清除。