Отдельный сценарий 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;
}
// Doesn't work for navigation properties!
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
});
Прикрепленный сценарий (вы загрузитепользователь из БД перед обновлением):
Вы можете изменить свой метод Save, чтобы принимать делегата, чтобы вы могли контролировать, как будет выполняться обновление:
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
{
// New object - all properties should be saved
context.Users.AddObject(user);
}
context.SaveChanges();
return user;
}
Вы будете вызывать методвот так:
var user = GetUpdatedUserFromSomewhere();
repository.Save(user, (dbUser, mergedUser) =>
{
dbUser.Email = mergedUser.Email;
});
В любом случае, несмотря на мои примеры, вам обязательно стоит подумать о публикации Дарина и специальных ModelViews для обновления.