这是表格
用户
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..
}
当前回答
实体框架跟踪您通过DbContext从数据库查询的对象的更改。例如,如果你的DbContext实例名是DbContext
public void ChangePassword(int userId, string password){
var user = dbContext.Users.FirstOrDefault(u=>u.UserId == userId);
user.password = password;
dbContext.SaveChanges();
}
其他回答
我用这个:
实体:
public class Thing
{
[Key]
public int Id { get; set; }
public string Info { get; set; }
public string OtherStuff { get; set; }
}
数据库上下文:
public class MyDataContext : DbContext
{
public DbSet<Thing > Things { get; set; }
}
访问器代码:
MyDataContext ctx = new MyDataContext();
// FIRST create a blank object
Thing thing = ctx.Things.Create();
// SECOND set the ID
thing.Id = id;
// THIRD attach the thing (id is not marked as modified)
db.Things.Attach(thing);
// FOURTH set the fields you want updated.
thing.OtherStuff = "only want this field updated.";
// FIFTH save that thing
db.SaveChanges();
我使用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还是它只是没有任何值。换句话说,属性值只能被替换为另一个值,而不能被清除。
I know this is an old thread but I was also looking for a similar solution and decided to go with the solution @Doku-so provided. I'm commenting to answer the question asked by @Imran Rizvi , I followed @Doku-so link that shows a similar implementation. @Imran Rizvi's question was that he was getting an error using the provided solution 'Cannot convert Lambda expression to Type 'Expression> [] ' because it is not a delegate type'. I wanted to offer a small modification I made to @Doku-so's solution that fixes this error in case anyone else comes across this post and decides to use @Doku-so's solution.
问题是Update方法中的第二个参数,
public int Update(T entity, Expression<Func<T, object>>[] properties).
使用提供的语法调用此方法…
Update(Model, d=>d.Name, d=>d.SecondProperty, d=>d.AndSoOn);
你必须在第二个参数前面加上'params'关键字。
public int Update(T entity, params Expression<Func<T, object>>[] properties)
或者如果你不想改变方法签名,那么要调用Update方法,你需要添加'new'关键字,指定数组的大小,然后最后使用集合对象初始化语法来更新每个属性,如下所示。
Update(Model, new Expression<Func<T, object>>[3] { d=>d.Name }, { d=>d.SecondProperty }, { d=>d.AndSoOn });
在@Doku-so的例子中,他指定了一个表达式数组,所以你必须在数组中传递属性来更新,因为数组你还必须指定数组的大小。为了避免这种情况,您还可以更改表达式参数,使用IEnumerable而不是数组。
下面是@Doku-so解决方案的实现。
public int Update<TEntity>(LcmsEntities dataContext, DbEntityEntry<TEntity> entityEntry, params Expression<Func<TEntity, object>>[] properties)
where TEntity: class
{
entityEntry.State = System.Data.Entity.EntityState.Unchanged;
properties.ToList()
.ForEach((property) =>
{
var propertyName = string.Empty;
var 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);
}
entityEntry.Property(propertyName).IsModified = true;
});
dataContext.Configuration.ValidateOnSaveEnabled = false;
return dataContext.SaveChanges();
}
用法:
this.Update<Contact>(context, context.Entry(modifiedContact), c => c.Active, c => c.ContactTypeId);
@Doku-so提供了一种使用泛型的很酷的方法,我用这个概念来解决我的问题,但你不能使用@Doku-so的解决方案,在这篇文章和链接的帖子中,都没有人回答使用错误的问题。
public async Task<bool> UpdateDbEntryAsync(TEntity entity, params Expression<Func<TEntity, object>>[] properties)
{
try
{
this.Context.Set<TEntity>().Attach(entity);
EntityEntry<TEntity> entry = this.Context.Entry(entity);
entry.State = EntityState.Modified;
foreach (var property in properties)
entry.Property(property).IsModified = true;
await this.Context.SaveChangesAsync();
return true;
}
catch (Exception ex)
{
throw ex;
}
}
在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。