Sql server 实体框架。如何优雅地报告SQL约束错误
我有一个web应用程序:ExtJs前端-EntityFramework+SQL Server作为后端。让我们来看一个错误场景:Sql server 实体框架。如何优雅地报告SQL约束错误,sql-server,entity-framework,validation,extjs,extjs4,Sql Server,Entity Framework,Validation,Extjs,Extjs4,我有一个web应用程序:ExtJs前端-EntityFramework+SQL Server作为后端。让我们来看一个错误场景: 我对用户名有数据库约束(名称必须唯一) 我没有任何客户端验证(我应该吗?有没有办法使这种验证通用?) 如果我尝试插入同名用户,服务器将返回500错误 如果我在IIS开启的同一台机器上运行它,我会收到完整的错误消息(基本上是SQL异常描述和密钥冲突等),如果我在其他机器上运行它,我只会收到500个错误,没有错误消息 处理这个问题的最佳方法是什么?我需要以一些人类可读的
- 我对用户名有数据库约束(名称必须唯一)
- 我没有任何客户端验证(我应该吗?有没有办法使这种验证通用?)
- 如果我尝试插入同名用户,服务器将返回500错误李>
- 如果我在IIS开启的同一台机器上运行它,我会收到完整的错误消息(基本上是SQL异常描述和密钥冲突等),如果我在其他机器上运行它,我只会收到500个错误,没有错误消息
处理这个问题的最佳方法是什么?我需要以一些人类可读的格式告诉用户错误。我真的不想在IIS上打开错误消息,因为这不是一个好的做法 首先,我建议您在提交到客户机上的服务器之前进行验证,向用户提供即时反馈是一种很好的体验
第二,对于实际插入的选项,您可以考虑几个选项:
我没有看到您提到更新
用户名
,如果您允许此功能,您也必须在更新之前进行验证,因为在执行insert时存在相同的问题 我认为这里没有错误,但是违反了业务规则
我喜欢区分这两种情况,第一种是一些意外情况(如数据库连接丢失),第二种是可能发生的情况
对于错误,我认为恰当的做法是以一般方式通知用户(比如,“发生了意外错误”),因为这是用户无法纠正的,也不需要详细信息
另一方面,业务规则是用户可能理解并可以采取措施纠正的东西(这里是用户名约束)。所以应该通知用户
在我参与的项目中,我们有一种异常类型,BusinessException
。我们抛出一条消息,指出问题所在,并以人类可读的格式呈现。我们不会明确地尝试捕获这些异常,而是使用处理程序来管理它们。如果您使用的是MVC,那么有一个扩展钩子,您可以在其中执行此操作
对于其他类型的异常,最好将stacktrace记录在某个位置(即EventViewer),但不向用户提供详细信息
在这种情况下,我将执行以下操作:
- 使用按钮检查名称以允许用户预先验证名称
- 验证名称的位置取决于您希望将应用程序的业务逻辑放在何处。在DB上,使用存储过程是一种方法,但如果使用EF,这意味着您希望从数据访问中抽象出来。相反,您可以使用
(类似于LINQ
然后检查它是否返回null或某个用户。您可能认为此验证不是必需的,因为您已经有了DB约束,但这样做,逻辑仍保留在应用程序的代码中Context.Users.SingleOrDefault(x=>x.Name==Name))自己编写此验证
- 从EF捕获异常可能很麻烦,因为您需要检查SQL错误代码以确定它是违反约束还是其他错误。即使您确定了这一点,您也需要将消息转换为用户友好的消息
始终捕获代码中的异常并将其记录下来。向用户显示有关错误的友好消息。永远不要向最终用户显示异常的堆栈跟踪。如果使用ASP.NET,请使用自定义错误页功能。如果使用DbContext,则可以通过自定义内置验证来验证其唯一性。请看这篇博客:。最后有一个示例演示了如何执行此操作。我同意客户端验证。我真的不想有数百个存储过程,我希望在EntityFramework中找到一种通用方法来返回可接受的错误。你知道类似的事情吗?我的意思是我不知道nt有权访问CommitChanges功能(我用它来做这件事)-EF会自动将所有内容传输到InsertXXXX/Updatexx。感谢您的完整回答。我会像您所说的那样研究LINQ验证。我完全同意您的“业务与内部”错误点