2012-10-05 35 views
1

使用Entity Framework和IEnumerables的好处之一是,您不必担心数据从数据库中实际查询的时间。您只需传递查询结果,当实际需要时,EF会为您提供。但是,如果要在您的SELECT代码中加入try/catch,那么它就成了一个问题,因为找出数据库将要被查询的时间并不容易。SELECT在实体框架中的异常处理

我现在正在收到间歇性的DB超时,并且我想记录EF在发生此事时使用的SQL,但是我遇到了上述刚刚描述的问题。有没有方便的方法来处理这个问题?或者我看错了问题?

回答

1

你知道什么时候执行查询,例如, .ToList(),.FirstOrDefault(), .Any()等 所以你应该把你的try catch块围绕它们。

+0

是否有任何方法来设置一个默认异常处理程序的EF所有这些或类似的东西?或者像一个默认的SQLException处理程序? – JoeCool

4

无论何时执行您期望的可能除外的代码功能块(因为在这种情况下,无论何时对EF数据上下文执行lamba表达式和/或LINQ查询),都应该使用正确的try/catch错误处理。真正的问题是你为什么收到超时。

我想恭敬地指出一个潜在的错误与您的上述声明,可能会提供一些诊断和修复您的超时帮助。 “......您不必担心数据从数据库中实际查询的时间。”我建议在构建一个名义上复杂的LINQ查询的过程中,您实际上需要非常清楚数据库何时会被击中。您将希望尽可能长时间保持LINQ查询为IQueryable,然后通过调用ToList(),Distinct(),Count()等对它们进行处理。

因此,让我们假设您正在查询一百万行表,并且您正在解析潜在的标准,您应该等到最后才能使用ToList()实现查询,因为这是由EF生成的SQL语句将在db上执行的点:

using(var context = CreateEFContextFactory()) 
{ 
    var x = (from d in context.MyBigTable select d); 
    if(!string.IsNullOrWhitespace(stringParam1)) 
     x = (from d in x where x.Field1 == stringParam1 select d); 
    if(intParam2 > 0) 
     x = (from d in x where x.Field2 == intParam2 select d); 

    var listOfMyBigTableObjects = x.Distinct().ToList(); //point of sql execution 
} 
+0

这绝对有道理,我完全同意你应该尽可能长时间保持它为IQueryable。我想我可能有这样的误解,认为LINQ可能会在某些时候或某事早期实现它 - 没有任何保证,但我想这不是事实。 – JoeCool