簡體   English   中英

使用EF Core的JSON的Ajax調用失敗/中止

[英]Ajax call for JSON using EF Core is failing/aborting

我不知道為什么這不起作用...

我有一個使用EF Core的.NET Core應用程序,並且正在通過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和EF6。如果我檢索偽數據(即IE而不是使用EF Core來獲取數據,我將偽造的數據返回到控制器中),這也可以使用。 是什么賦予了?

澄清問題的根源:您正在查詢數據庫並返回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周圍使用了block(這是正確的。請參閱最后的評論)。

因此,要修復此問題,基本上您需要自己枚舉結果或不關閉連接(請在請求完成后讓框架為您關閉)。 此較小的更改解決了該問題:

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

其他評論:您不需要(也不應該)自己管理dbContext的創建。 您可以在DI容器中注冊它,框架將為您完成其余工作。 您可以在EF Core文檔中查看有關如何完成操作的想法。

這不是一個理想的解決方案,但我可以正常使用。 我懷疑這可能與.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);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM