.net – 从何处运行实体的重复检查
我正在寻找关于“最佳”放置验证逻辑的建议,例如在MVC应用程序中使用Entity Framework Code-First时对实体进行重复检查.
使用一个简单的例子: public class JobRole { public int Id { get; set; } public string Name { get; set; } } 规则是“名称”字段必须是唯一的. 当我添加一个新的JobRole时,很容易在Job Role Repository中运行一个名称尚不存在的检查. 但是,如果用户编辑现有JobRole,并意外将名称设置为已存在的名称,我该如何检查? 问题是存储库中不需要“更新”方法,因为作业角色实体将自动检测更改,因此在尝试保存之前没有合理的位置来执行此检查. 到目前为止,我考虑了两个选项: >覆盖DbContext上的ValidateEntry方法,然后在使用EntityState.Modified保存JobRole实体时,运行重复检查. 两者都不是真的很理想.使用ValidateEntry似乎相当晚(在保存之前)并且难以测试.使用服务可能会有人忘记从控制器调用它,让重复的数据通过. 有没有更好的办法? 解决方法
您对ValidateEntity的问题似乎是在SaveChanges上进行验证,这对您来说太迟了.但是在Entity Framework 5.0中,如果您希望使用
DbContext.GetValidationErrors,则可以提前调用验证.当然,您也可以直接调用
DbContext.ValidateEntity.我是这样做的:
>覆盖DbContext上的ValidateEntity方法: protected override DbEntityValidationResult ValidateEntity(DbEntityEntry entityEntry,IDictionary<object,object> items) { //base validation for Data Annotations,IValidatableObject var result = base.ValidateEntity(entityEntry,items); //You can choose to bail out before custom validation //if (result.IsValid) // return result; CustomValidate(result); return result; } private void CustomValidate(DbEntityValidationResult result) { ValidateOrganisation(result); ValidateUserProfile(result); } private void ValidateOrganisation(DbEntityValidationResult result) { var organisation = result.Entry.Entity as Organisation; if (organisation == null) return; if (Organisations.Any(o => o.Name == organisation.Name && o.ID != organisation.ID)) result.ValidationErrors .Add(new DbValidationError("Name","Name already exists")); } private void ValidateUserProfile(DbEntityValidationResult result) { var userProfile = result.Entry.Entity as UserProfile; if (userProfile == null) return; if (UserProfiles.Any(a => a.UserName == userProfile.UserName && a.ID != userProfile.ID)) result.ValidationErrors.Add(new DbValidationError("UserName","Username already exists")); } >在try catch中嵌入Context.SaveChanges并创建一个访问Context.GetValidationErrors()的方法.这是在我的UnitOfWork类中: public Dictionary<string,string> GetValidationErrors() { return _context.GetValidationErrors() .SelectMany(x => x.ValidationErrors) .ToDictionary(x => x.PropertyName,x => x.ErrorMessage); } public int Save() { try { return _context.SaveChanges(); } catch (DbEntityValidationException e) { //http://blogs.infosupport.com/improving-dbentityvalidationexception/ var errors = e.EntityValidationErrors .SelectMany(x => x.ValidationErrors) .Select(x => x.ErrorMessage); string message = String.Join("; ",errors); throw new DataException(message); } } >在我的控制器中,在将实体添加到上下文之后但在SaveChanges()之前调用GetValidationErrors(): [HttpPost] public ActionResult Create(Organisation organisation,string returnUrl = null) { _uow.OrganisationRepository.InsertOrUpdate(organisation); foreach (var error in _uow.GetValidationErrors()) ModelState.AddModelError(error.Key,error.Value); if (!ModelState.IsValid) return View(); _uow.Save(); if (string.IsNullOrEmpty(returnUrl)) return RedirectToAction("Index"); return Redirect(returnUrl); } 我的基础存储库类实现了InsertOrUpdate,如下所示: protected virtual void InsertOrUpdate(T e,int id) { if (id == default(int)) { // New entity context.Set<T>().Add(e); } else { // Existing entity context.Entry(e).State = EntityState.Modified; } } 我仍然建议为数据库添加一个唯一约束,因为这绝对可以保证您的数据完整性并提供可以提高效率的索引,但是覆盖ValidateEntry可以控制验证的发生方式和时间. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net – 部署后SQL不会连接
- asp.net – AngularJs 2与ASP.NET 4.5.1
- asp.net – 在Gridview中有条件地隐藏CommandField或Button
- asp.net – 在MS Access 2003中INSERT到用户表中的语法错误
- asp.net – Elmah vs Elmah.MVC Nuget软件包 – 哪些使用和
- asp.net-mvc – 如何在ASP.NET MVC中执行[RequireHttps(Red
- 从ViewBag设置文本输入的值? ASP.NET MVC5
- asp.net-mvc – 使用HTML.EditorFor Vs使用HTML.CheckBox
- 10.1.翻译系列:EF 6中的实体映射【EF 6 Code-First系列】
- asp.net-mvc – ASP.NET MVC内联Razor变量
- 为什么ASP.NET回发时请求cookie属性为null或不正
- ASP.NET Bundling – 忽略第二个JS文件
- asp.net-mvc – 获取ASP.Net MVC中任何文件的完整
- ASP.NET MVC和SQL Server报告服务
- asp.net-mvc – asp.net mvc禁用ajax缓存
- asp.net-mvc – 如何为未经过身份验证的用户隐藏
- asp.net-mvc – Asp.Net MVC Html助手扩展
- asp.net-core – HttpResponse不包含Dot Net Cor
- ASP.NET 性能优化之反向代理缓存使用介绍
- asp.net-mvc – 在ASP.NET MVC控制器结果中设置H