显示常见EF Delete语句与引用约束冲突的友好错误
本文关键字:冲突 错误 约束 引用 EF 常见 Delete 语句 显示 | 更新日期: 2023-09-27 18:24:55
我有一个由实体框架支持的WebApi 2服务。当用户试图删除一个与其他实体相关的实体时,我只想向他们显示一条消息,说明他们无法删除该特定项目,因为其他项目与之有关系,然后跳过删除。
我认为这是一个相当常见的场景。我目前正在使用try-catch语句在HTTP响应消息中抛出友好消息。这对我来说就像是一个黑客……我很想听听其他关于处理这件事的建议。
public async Task<IHttpActionResult> DeleteAsync(int id)
{
try
{
var entity = await TheContext.Fluids.FindAsync(id);
if (entity == null) return NotFound();
TheContext.Fluids.Remove(entity);
await TheContext.SaveChangesAsync();
}
catch (Exception ex)
{
if (CannotDeleteDueToExistingRelationship(ex))
ThrowForbiddenCannotDeleteDueToExistingRelationship();
}
return Ok();
}
//Methods in base controller
protected void ThrowForbiddenCannotDeleteDueToExistingRelationship()
{
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.Forbidden)
{
Content = new StringContent(string.Format("This entity has a relationship to another item and cannot be deleted.")),
ReasonPhrase = "Relationship requires entity."
});
}
protected bool CannotDeleteDueToExistingRelationship(Exception ex)
{
if (ex.InnerException.InnerException.Message.Contains("The DELETE statement conflicted with the REFERENCE constraint"))
{
return true;
}
return false;
}
找到它后,答案非常简单。WebAPI 2允许您使用属性过滤器。
public class DeleteConflictsWithReferenceConstraintExceptionAttribute : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext context)
{
if (context.Exception is DbUpdateException)
{
if (!(context.Exception as DbUpdateException).InnerException.InnerException.Message.Contains("The DELETE statement conflicted with the REFERENCE constraint")) return;
var response = new HttpResponseMessage(HttpStatusCode.Forbidden)
{
Content = new StringContent(string.Format("This entity has a relationship to another item and cannot be deleted.")),
ReasonPhrase = "Relationship requires entity."
};
context.Response = response;
}
}
}
然后在WebApiConfig中注册。
private static void WebApiConfig(IAppBuilder app)
{
var webApiConfig = new HttpConfiguration();
webApiConfig.SuppressDefaultHostAuthentication();
// Web API filters
webApiConfig.Filters.Add(new DbEntityValidationExceptionAttribute());
webApiConfig.Filters.Add(new DeleteConflictsWithReferenceConstraintExceptionAttribute());
}
这避免了在任何地方都有相同的异常逻辑。