.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-mvc-3 – 可用会员入门套件/成员资料用于ASP.NET M
- asp.net-mvc – 我们可以从现有数据库的选定表中Scaffold D
- asp.net – Mocking HttpContext不起作用
- asp.net-mvc-4 – GAC问题不能在IIS上托管应用程序
- asp.net-mvc – Unity PerRequestLifetimeManager在不同请求
- asp.net-core – 在ASP.NET Core中使用Entity Framework 6
- asp.net-mvc-4 – DataAnnotation Range属性的客户端验证之
- asp.net-mvc – ELMAH MVC 2 – Castle Windsor的问题
- asp.net-mvc-3 – ASP.Net MVC 3不显眼的验证不适用于部分视
- asp.net-mvc – 我的模型中名为Title的属性与我视图中的Vie
- asp.net-mvc – 获取Controller.OnException中的
- ASP.NET Web应用程序(MVC)部署自动化和Subversio
- asp.net – WebForm_DoPostBackWithOptions没有使
- asp.net – 如何使用jQuery ajax避免快速结果的“
- 如何在ASP.Net内容页面中添加元标记
- asp.net-mvc – 在cshtml中折叠C#块并保存
- asp.net-mvc – 基于Route Params的ASP.NET MVC授
- asp.net下Cache 缓存操作类代码
- asp.net-web-api – MVC Web API不能与Autofac集
- 我如何在ASP.NET MVC中使用Application_Error?
