我不知道为什么这不起作用......
我有一个使用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来获取数据,我返回伪造的数据进入控制器。是什么给了什么?
答案 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);
}
}