使用EF Core对Ajax进行Ajax调用失败/中止

时间:2017-06-15 18:11:24

标签: asp.net-core asp.net-core-mvc entity-framework-core

我不知道为什么这不起作用......

我有一个使用EF Core的.NET Core应用程序,我正在通过jQuery对我的控制器进行Ajax调用,以通过EF Core从数据库中检索一些数据。通过浏览器(IE / Chrome)中的开发人员工具调试呼叫会导致失败/中止状态。然而,当我在控制器中逐步执行我的方法时,该方法似乎能够通过EF Core从数据库中检索数据。

这是我的控制器:

$(#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
                    }
                }) 
            }
        }, 
    }, 
   ....
});

这是jQuery:

this

Ajax调用可以使用我曾经使用的以前的应用程序,但是他们使用的是MVC 5和EF 6.如果我检索虚拟数据,IE也可以使用,而不是使用EF Core来获取数据,我返回伪造的数据进入控制器。是什么给了什么?

2 个答案:

答案 0 :(得分: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,了解它是如何完成的。

答案 1 :(得分: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);
    }
}