这里是表格
用户
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..
}
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 解决方案的实现。
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的解决方案,在这篇文章和链接的文章中都没有人回答使用错误的问题。
entityEntry.State = EntityState.Unchanged;
这一行时,我正在处理您的解决方案。此时,参数entityEntry
中的所有更新值都会被还原,因此不会保存任何更改。请问您能否帮忙解决这个问题?谢谢。 - sairfan结合几个建议,我提出以下方案:
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;
ValueInjecter
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();
}
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);
查看这个答案。
你将不知道属性是否有意被清空为null,还是本来就没有任何值。换句话说,属性值只能被替换为另一个值,而不能被清除。
_context.Users.UpdateProperty(p => p.Id, request.UserId, new UpdateWrapper<User>()
{
Expression = p => p.FcmId,Value = request.FcmId
});
await _context.SaveChangesAsync(cancellationToken);
更新属性是一个扩展方法
public static void UpdateProperty<T, T2>(this DbSet<T> set, Expression<Func<T, T2>> idExpression,
T2 idValue,
params UpdateWrapper<T>[] updateValues)
where T : class, new()
{
var entity = new T();
var attach = set.Attach(entity);
attach.Property(idExpression).IsModified = false;
attach.Property(idExpression).OriginalValue = idValue;
foreach (var update in updateValues)
{
attach.Property(update.Expression).IsModified = true;
attach.Property(update.Expression).CurrentValue = update.Value;
}
}
更新包装器是一个类
public class UpdateWrapper<T>
{
public Expression<Func<T, object>> Expression { get; set; }
public object Value { get; set; }
}
IsModified = true
”。它真的有什么新东西可以展示另一种方法吗?这也不是被问到的。旧问题收集越来越多的噪音是Stack Overflow上相当烦人的问题。 - Gert Arnold我一直在寻找同样的问题,最终我找到了解决方案。
using (CString conn = new CString())
{
USER user = conn.USERs.Find(CMN.CurrentUser.ID);
user.PASSWORD = txtPass.Text;
conn.SaveChanges();
}
相信我,它对我来说像魔法一样有效。
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;
}
}
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();
}
}