所有获取数据库对象的linq都应该被try-catch包围吗

本文关键字:try-catch 包围 linq 获取 数据库 对象 | 更新日期: 2023-09-27 18:28:54

所有返回实体的linq查询都应该用try-catch包围吗?

例如:

phase.Container = containers.Where(cont => cont.ContainerId == phase.ContainerId).SingleOrDefault();

这不会导致应用程序崩溃,但如果Container对象不存在,则会导致异常。

编辑

即使这样做仍然会导致视图出现异常:

bool schedValid = false;
foreach (var s in schedules)
{
 if (s.ScheduleId == phase.ScheduleId) schedValid = true;
}
if (schedValid)
{
 phase.Schedule = schedules.SingleOrDefault(sc => sc.ScheduleId == phase.ScheduleId);
}
else
{
 phase.Schedule = null;
}

编辑2

所有这些努力的原因是,如果父对象被删除,那么包含数据的子对象仍然应该被允许查看,即使它们的父对象已经不在了。可以提出一个参数,即不应允许删除父对象。这很公平,但当孩子变得比父母更重要时,无论出于何种原因,父母都不再需要留下来,保持这种关系是没有意义的。稍后,可能会将子对象重新分配给不同的父对象。

所有获取数据库对象的linq都应该被try-catch包围吗

这是对标题中问题的回应,而不是问题正文中给出的具体示例。

"这取决于"

当异常发生时,你打算怎么办?你能合理地回应数据库错误吗?如果没有,请不要捕获异常。如果您能够以允许应用程序的其余部分继续执行的方式进行合理的响应,那么就捕获异常。

有关异常处理的更多详细信息,请参阅Eric Lippert的这篇精彩文章
http://blogs.msdn.com/b/ericlippert/archive/2008/09/10/vexing-exceptions.aspx

好吧,它会抛出一个异常,只要你在堆栈的某个地方管理你的异常,那么你可能不需要包装你使用的每个LINQ。

您可以使用默认/宽消息处理LINQ可能引发的常见异常,并处理LINQ中更精确的错误。

以下是从这个问题中可以抛出的已知异常列表:

  • SqlException
  • ChangeConflictException
  • DuplicateKeyException
  • ForeignKeyReferenceAlreadyHasValueException
  • OutOfMemoryException(未正确处理DataContext时)

知道这些错误会被抛出,你很可能会发现一个瓶颈,在那里捕捉这些错误并相应地处理它们会很有趣,如果是用户应用程序,那么可能会显示一个错误框,其中包含一些友好的文本来描述错误类型(例如:外键异常意味着记录仍在某个地方使用)。

如果您知道一个精确的LINQ表达式会给您带来麻烦,那么您可以使用Try/Catch对其进行单独的处理并进行相应的管理。

我能看到的唯一由代码片段引发的异常(假设它是编译的)是NRE。如果phasecontainers为null,或者containers包含null值,则最终会出现NullReferenceException。

不过,我预计代码中会有这些,以避免在使用前明确检查它们的值来使用try/catch

if (phase != null && containers != null)
    phase.Container = containers
                        .Where(cont => cont != null)
                        .SingleOrDefault(cont => cont.ContainerId == phase.ContainerId);

例外情况很昂贵。。。尽你所能避开他们。


更新

考虑到您当前的设计有意孤立记录,并且您不能真正信任您的数据库,我建议您在所有代码中使用try/catch块。。。

糟糕的数据库/应用程序设计需要同样糟糕的代码。

这里的正确答案是修复你的设计。