2017-06-15 95 views
0

我在用,爲什麼這是行不通的損失......Ajax調用的JSON失敗/中止

我使用EF核心.NET的核心應用程序,我正在做通過jQuery向我的控制器發送Ajax調用,以通過EF Core從數據庫檢索一些數據。通過瀏覽器中的開發人員工具(IE/Chrome)調試通話會導致失敗/中止狀態。但是當我在我的控制器中遍歷我的方法時,該方法似乎能夠通過EF Core從數據庫中檢索數據。

這裏是我的控制器:

public ActionResult GetInfo(string term) 
{ 
    using (var dbContext = new DatabaseContext()) 
    { 
     // use DbContext to get data from the database 
     var retrievedData = dbContext.TableName.Where(...); 
     return Json(retrievedData.Select(data => new { 
      id = data.id, 
      text = data.text 
     })); 
    } 
} 

而這裏的jQuery的:

$(#element).select2({ 
    ... 
    ajax: { 
     url: $(#element).attr("data-getinfo"), 
     dataType: 'json', // tried this with jsonp and application/JSON with no luck 
     contentType: 'application/json; charset=utf-8', 
     delay: 250, 
     data: function (params) { 
      return: { term: params.term}; 
     }, 
     processResults: function (data) { 
      return { 
       results: $.map(data, function (item) { 
        return { 
         id: item.id, text: item.text 
        } 
       }) 
      } 
     }, 
    }, 
    .... 
}); 

Ajax調用與以前的應用程序,我的工作就工作,但他們使用MVC 5和EF 6.本如果我檢索虛擬數據,也可以使用IE,而不是使用EF Core來獲取數據,我返回內置於控制器中的假數據。是什麼賦予了?

+0

dbcontext的使用在哪裏? –

+0

@ roy.d dbContext用於獲取數據並將其存儲在retrieveData中。我爲了簡單起見而剪掉它,但是我可以編輯它。 –

+0

我很喜歡90%確定這行'url:$(#element).attr(「data-getinfo」),'是原因 – Hackerman

回答

2

澄清問題的根源:您正在查詢數據庫並將IEnumerable作爲JsonResult返回。但首先,你需要先了解一步。調用.Where會返回一個IQueryable。您可以將IQueryable看作是尚未在數據庫上執行的TSQL命令。只有將枚舉爲的調用結果纔會觸發查詢的實現。

所以,你這樣做:

// .Where returns an IQueryable. You can "chain" more wheres later. 
// the query will still not be executed 
var retrievedData = dbContext.TableName.Where(...); 


// This then returns an IEnumerable to the client. 
// The Select will materialize (execute) the query 
return Json(retrievedData.Select(data => new { 
    id = data.id, 
    text = data.text 
})); 

的問題與您的代碼是:.Select返回一個IEnumerable其中列舉的結果。但是,當瀏覽器或你正在處理的任何客戶端開始枚舉結果時,你的數據庫連接已經關閉了,因爲你在dbContext中使用了塊(這是正確的......見最後的註釋)。

所以,要解決它,你基本上需要自己枚舉結果或者不關閉連接(當請求完成時讓框架關閉)。這種微小的變化解決這個問題:

// ToList() will enumerate all the results in memory 
var retrievedData = dbContext.TableName.Where(...).ToList(); 

其他評論: 你並不需要自己(也不能)管理的DbContext的創建。您可以將它註冊到DI容器中,框架將爲您完成剩下的工作。您可以查看EF Core docs,瞭解它是如何完成的。

+0

嗯,現在我覺得很蠢。我在之前的代碼/應用程序中使用了ToList/AsEnumerable,因爲我之前遇到過這個懶加載問題,但我忘了把它拋進去,我沒有意識到這實際上是原因......大聲笑。這解釋了很多。 –

0

不是一個理想的解決方案,但我得到它的工作。我懷疑它可能與.NET Core或EF Core如何將數據返回到瀏覽器有關,但我目前還不能確定。

我結束了使用Json.NET的解決方法。性能並不差(我嘗試了一個包含數百條記錄的查詢,最多隻需要幾秒鐘),而且我已經將它用於外部API調用。

public ActionResult GetInfo(string term) 
{ 
    using (var dbContext = new DatabaseContext()) 
    { 
     // use DbContext to get data from the database 
     var retrievedData = dbContext.TableName.Where(...); 

     var initJson = Json(retrievedData.Select(data => new { 
      id = data.id, 
      text = data.text 
     })); 

     var serializedJson = Newtonsoft.Json.JsonConvert.SerializeObject(initJson); 
     var deserializedJson = Newtonsoft.Json.JsonConvert.DeserializeObject(serializedJson); 
     return Json(deserializedJson); 
    } 
} 
+0

看到我上面的答案。你有更大的問題:) – jpgrassi