MVC在以某种方式返回语句之后枚举结果*吗?

时间:2011-06-27 20:20:20

标签: c# asp.net-mvc linq-to-sql

我的代码如下:

 [HttpPost]
 public ActionResult CustomerSearch(string firstName ...
 {
 ...
 try 
 {
   var results = from t in db.Customers... 
   var custResults = results.Select(c=> new string[] { ... });
   return this.Json(custResults );
 }    
 catch (TimeoutException exc1)
 { 
    return this.Json(new {error = "Search failed (timeout)"});   
 }
 catch (System.Exception exc)
 { ... }
}

我通过将sql调用的超时设置为小(5s)来测试它。确实发生了异常,我可以在我的日志中看到它并且protected override void OnException事件正在触发。但是TimeoutExceptionException的捕获量永远不会受到影响。我怀疑MVC是如何工作的,我不理解。

奇怪的是,如果我在return this.Json(custResults);上设置断点,我可以毫无问题地通过该行。但是如果我在ToList()上放置一个.Select(..),那么将抛出TimeoutException。在执行return语句后,MVC如何枚举结果集?

2 个答案:

答案 0 :(得分:3)

Json可能是一种惰性方法,因为它不会枚举给定的结果集。相反,它将结果集包装在另一个枚举器中。这意味着在MVC需要结果之前,SQL永远不会被执行。鉴于您的函数不执行枚举但MVC执行,这会导致异常发生在您无法将其包装在try / catch块中的情况。

正如您在帖子中提到的,添加ToList()会导致集合和存储的枚举进入某个位置,从而导致异常发生在您期望的位置。

答案 1 :(得分:0)

Select()调用将创建一个延迟(懒惰)枚举

http://msdn.microsoft.com/en-us/library/bb548891.aspx

  

此方法通过使用延迟执行来实现。立即返回值是一个对象,它存储执行操作所需的所有信息。直到通过直接调用其GetEnumerator方法或在Visual C#中使用foreach或在Visual Basic中使用For Each来枚举对象时,才会执行此方法表示的查询。

执行ToList()或ToArray()将从中创建非延迟集合