asp.net-mvc – 存储库模式中的纯POCO实体更新问题
发布时间:2020-12-16 00:12:20 所属栏目:asp.Net 来源:网络整理
导读:我的UserRepository中有一个问题,我想在其中更新用户.除非指定,否则我不希望更新某些字段,例如密码.例如,当我将用户从视图传递到服务器到存储库时,它会向用户发送空密码或空密码字符串.这个null被写入数据库(我不想要). 我该如何处理这种情况? 域 public cl
我的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.在我的情况下,数据库抛出错误,因为密码应该可以为空. 解决方法
分离的POCO场景(更新前不会从DB加载用户):
您可以有选择地说明必须更新哪些属性: 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 }); 附加方案(您将在更新前从DB加载用户): 您可以修改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; }); 无论如何,尽管有我的例子,你一定要考虑Darin的帖子和特殊的ModelViews进行更新. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- asp.net – 这个LINQ statment是否容易受SQL注入攻击?
- asp.net-mvc – 你相信ASP.Net MVC已经准备好了吗?
- wcf – .Net Core ReportExecutionServiceSoapClient设置凭
- Asp.net 代码设置兼容性视图
- asp.net-core – CSS,图片,JS没有加载asp.net核心:(
- ASP.Net / C#:替换数据绑定字段中的字符
- asp.net-web-api – 不能构造String类型
- asp.net-mvc – 在ASP.NET MVC中获取当前操作/控制器的自定
- 如何在asp.net中打开MS Office word?
- .net – .ToTitleCase不适用于所有大写字符串
推荐文章
站长推荐
热点阅读