使用Entity Framework和IEnumerables的一个很好的功能是,您不必担心何时从数据库中实际查询数据。您只需传递查询结果,实际需要时,EF会为您提供。但是,当涉及到对SELECT代码进行try / catch时,它就成了一个问题,因为要确定何时查询数据库并不容易。
我现在正在获得间歇性的DB超时,我想记录EF在发生时使用的SQL,但是我遇到了上面刚才描述的问题。有没有方便我处理这个问题?还是我看错了?
答案 0 :(得分:4)
每当执行您期望的功能代码块时,您应该使用正确的try / catch错误处理(在这种情况下,无论何时对EF数据上下文执行lamba表达式和/或LINQ查询)。真正的问题是你为什么收到超时。
我谨恭敬地指出您的上述陈述可能有助于诊断和解决您的超时问题。 “......你不必担心何时从数据库中查询数据。”我建议在构建一个名义上复杂的LINQ查询的过程中,你确实需要非常清楚数据库何时会受到攻击。您希望尽可能长时间地将LINQ查询保持为IQueryable,然后通过调用ToList(),Distinct(),Count()等来对它们进行重新定位。
所以让我们说你正在查询一个百万行的表并且你正在解析潜在的标准,你应该等到最后用ToList()来实现查询,因为这是生成SQL语句的点。通过EF将在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
}
答案 1 :(得分:1)
您知道何时执行查询,例如.ToList()
,.FirstOrDefault()
,.Any()
等
所以你应该把try catch
块放在它们周围。
答案 2 :(得分:1)
听起来你在这里做了几件事:view the SQL that is being generated by Entity Framework,然后添加global error handler。
如果您正在编写.NET Web应用程序或api,则可以添加默认错误处理程序,如elmah。如果您正在使用MVC,global error handler的答案演示了将elmah设置为全局处理程序,但您可以轻松自定义该示例,以使用您自己的日志记录实用程序。