分离的POCO场景(在更新之前不会从数据库中加载用户):
您可以选择性地指定要更新的属性:
public User Save(User user)
{
if (user.UserId == 0)
{
context.Users.AddObject(user);
}
else
{
context.Users.Attach(user);
ObjectStateEntry entry = context.ObjectStateManager.GetObjectStateEntry(user);
entry.SetModifiedProperty("Email");
}
context.SaveChanges();
return user;
}
你也可以创建两个重载版本的
Save
方法。第一个将更新整个对象,第二个将仅更新显式选择的属性:
public User Save(User user)
{
if (user.UserId == 0)
{
context.Users.AddObject(user);
}
else
{
context.Users.Attach(user);
context.ObjectStateManager.ChangeObjectState(user, EntityState.Modified);
}
context.SaveChanges();
return user;
}
public User Save(User user, IEnumerable<Expression<Func<User, object>>> properties)
{
if (user.UserId == 0)
{
context.Users.AddObject(user);
}
else
{
context.Users.Attach(user);
ObjectStateEntry entry = context.ObjectStateManager.GetObjectStateEntry(user);
foreach(var selector in properties)
{
string propertyName = PropertyToString(selector.Body);
entry.SetModifiedProperty(propertyName);
}
}
context.SaveChanges();
return user;
}
private static string PropertyToString(Expression selector)
{
if (selector.NodeType == ExpressionType.MemberAccess)
{
return ((selector as MemberExpression).Member as PropertyInfo).Name;
}
throw new InvalidOperationException();
}
您将以以下方式调用第二个重载函数:
userRepository.Save(user, new List<Expression<Func<User, object>>>
{
u => u.Email
});
附加场景(在更新之前,您将从数据库中加载用户):
您可以修改保存方法以接受委托,以便您可以控制如何执行更新:
public User Save(User user, Action<User, User> updateStrategy)
{
if (user.UserId > 0)
{
User dbUser = context.Users.FirstOrDefault(u => u.UserId == user.UserId);
updateStrategy(dbUser, user);
}
else
{
context.Users.AddObject(user);
}
context.SaveChanges();
return user;
}
你可以这样调用该方法:
var user = GetUpdatedUserFromSomewhere();
repository.Save(user, (dbUser, mergedUser) =>
{
dbUser.Email = mergedUser.Email;
});
无论如何,尽管我提供了一些例子,但你一定要考虑Darin的帖子和用于更新的特殊ModelViews。