存储库模式中的纯 POCO 实体更新问题
我的 UserRepository 遇到问题,我想更新用户。我不希望更新某些字段,例如密码,除非指定。例如,当我将用户从视图传递到服务到存储库时,它会向用户发送 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;
}
可以说,在这种情况下,我的视图允许我仅更改电子邮件
,因此唯一发送回Save()
方法是:user.UserId
和user.Email
,而user.Password
为null。就我而言,数据库会抛出错误,因为密码应该可为空。
I have a problem in my UserRepository in which I want to update a user. I dont want certain fields updated, such as password, unless specified. For example, When I pass the User from the view, to the service to the repository, it sends up the user with a null or empty password string. This null gets written to the database (which I dont want).
How do I handle a situation like this?
Domain
public class User
{
public int UserId { get; set; }
public string Email { get; set; }
public string Password { get; set; }
}
Repository
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;
}
Lets say in this case, my view allows me to change only Email
, so the only thing that gets sent back to the Save()
method are: user.UserId
and user.Email
while user.Password
is null. In my case, the database throws error because Password should be nullable.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
分离的 POCO 场景(更新前不会从数据库加载用户):
您可以有选择地指定必须更新哪些属性:
您还可以创建
Save
方法的两个重载。第一个将更新整个对象,第二个将仅更新显式选择的属性:您将这样调用第二个重载:
附加场景(您将在更新之前从数据库加载用户):
您可以将 Save 方法修改为接受委托,以便您可以控制更新的执行方式:
您将这样调用该方法:
无论如何,尽管有我的示例,您绝对应该考虑 Darin 的帖子和用于更新的特殊 ModelView。
Detached POCO scenario (you will not load user from DB before update):
You can selectively say which properties must be updated:
You can also create two overloads of you
Save
method. First will update whole object, second will update only explicitly selected properties:You will call the second overload this way:
Attached scenario (you will load user from DB before update):
You can modify your Save method to accept delegate so that you can control how update will be performed:
You will call the method this way:
Anyway, despite of my examples you should definitely think about Darin's post and special ModelViews for updating.
您应该使用视图模型。视图模型是专门根据视图的需要定制的类,并且仅包含该给定视图所需的属性。因此,您的控制器操作应该如下所示:
而不是:
在控制器操作内部,您可以在视图模型和模型之间进行映射。 AutoMapper 是一个可以简化此任务的出色工具。
你真的应该非常小心,永远不要像这样暴露你的模型。始终在视图中使用视图模型。试想一下,如果您的模型上有一个
IsAdministrator
布尔属性。You should use view models. View models are classes which are specifically tailored to the needs of a view and contain only the properties needed by this given view. So your controller action should look like this:
instead of:
Inside the controller action you could map between the view model and the model. AutoMapper is a great tool that could simplify this task.
You should really be very careful and never expose your models like this. Always use view models to and from a view. Just imagine if there was an
IsAdministrator
boolean property on your model.你能做到吗?
Can you do this?