DbContext.SaveChanges https://learn.microsoft.com/en-us/dotnet/api/system.data.entity.dbcontext.savechanges?view=entity-framework-6.2.0描述了您可能会遇到哪些例外情况。决定要捕获哪些异常,不捕获哪些异常。
如果您不确定在什么情况下会出现哪些异常,请使用调试器和一些测试代码来找出您实际上可能期望的异常:
// TODO: create one of your error conditions
try
{
_context.SaveChanges();
}
catch (Exception e)
{
Console.WriteLine(e.GetType()); // what is the real exception?
}
当您知道可以预期哪些异常以及真正可以处理哪些异常时,请编写最终代码:
try
{
_context.SaveChanges();
}
catch (DbUpdateException e)
{
// handle the update exception
}
catch (DbEntityValidationException e)
{
// handle the entity validation exception
}
catch (...)
您可能不会捕获 System.NotSupportedException,您的代码应该只使用受支持的 LINQ 语句。
优化
请记住,DbSets
在你的DbContext
代表数据库中的表。课程在DbSets
表示表中的行:非虚拟属性表示表中的列,表之间的关系表示为虚拟属性。
您设计这些数据库表是因为您想解决问题。显然,在您的解决方案中,名字/姓氏等不能为空很重要。
您可能会将 DbContext 的使用包装到一个类中,该类隐藏您使用实体框架来保存数据,而不是使用 Dapper 或任何较低级别的方法来查询和更新数据。
通常这个包装类被称为Repository
类别:您的用户Repository
不知道,也不在乎如何以及在何处保存数据:SQL?蒙戈?甚至可能是 CSV 文件?
拥有一个美好的事情Repository
类是,如果您决定更改表布局,或者决定将其中一个查询更改为存储过程,或者决定将数据存储在 CSV 中,则更改将是最小的,用户甚至不会注意变化
在您的存储库中,您将具有查询人员、添加/删除/更新人员等的功能。您之前决定您的解决方案不应接受具有空名称的人员。
您的解决方案不取决于数据的保存方式。因此,您的解决方案不应依赖于您的存储库是否检查您的名称是否为 null 或 nt。
考虑在调用 SaveChanges 之前检查数据有效性。在这种情况下:检查名字、姓氏等是否确实不为空。你的代码将
- 看起来更干净:减少对范围之外的各方抛出的异常的处理
- 更容易阅读:读者不必猜测如果数据为空会发生什么,
- 更容易测试:您的测试代码可以使用简单的模拟存储库,无需进行空检查
- 更好的可维护性:如果您决定允许添加没有名字的人员,您的数据库模型不会改变,只会改变您的存储库类