gpt4 book ai didi

asp.net-mvc - 存储库模式中的纯 POCO 实体更新问题

转载 作者:行者123 更新时间:2023-12-04 22:36:55 24 4
gpt4 key购买 nike

我在要更新用户的 UserRepository 中遇到问题。除非指定,否则我不希望更新某些字段,例如密码。例如,当我将用户从 View 传递到服务到存储库时,它会向用户发送一个 null 或空密码字符串。这个空值被写入数据库(我不想要)。

我该如何处理这样的情况?

域名

public class User
{
public int UserId { get; set; }

public string Email { get; set; }
public string Password { get; set; }
}

存储库
    public User Save(User user)
{
if (user.UserId > 0)
{
User dbUser = context.Users.FirstOrDefault(u => u.UserId == user.UserId);
//What do I do here?
}
context.Users.AddObject(user);
context.SaveChanges();
return user;
}

假设在这种情况下,我的观点只允许我更改 Email ,所以唯一被发送回 Save()方法是: user.UserIduser.Emailuser.Password一片空白。就我而言,数据库抛出错误,因为密码应该可以为空。

最佳答案

分离 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 方法以接受委托(delegate),以便您可以控制如何执行更新:
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;
});

无论如何,尽管有我的例子,你绝对应该考虑 Darin 的帖子和特殊的 ModelViews 进行更新。

关于asp.net-mvc - 存储库模式中的纯 POCO 实体更新问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4697203/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com