我有一个非常大的结果集,我想使用JSON返回Ajax调用。
我开始创建一个对象集合,然后序列化集合,但集合创建会抛出System.OutOfMemoryException。
我现在尝试更改实现以在没有集合的情况下流式传输JSON,但我仍然得到System.OutOfMemoryException。
这是我目前的代码片段。
using (var stream = new MemoryStream())
{
using (var streamWriter = new StreamWriter(stream))
{
using (var jsonWriter = new JsonTextWriter(streamWriter))
{
var serializer = new JsonSerializer();
serializer.Serialize(jsonWriter,new { pins = MakePins(model), missingLocations = 0 });
jsonWriter.Flush();
}
}
stream.Seek(0, SeekOrigin.Begin);
return new FileStreamResult(stream, "application/json");
MakePins功能如下所示:
var pinData = _geographyService.GetEnumerationQueryable()
.SelectMany(x => x.EnumeratedPersonRoleCollection)
.ApplyFilter(model).Where(x => x.EnumerationCentre.Location != null)
.AsNoTracking()
.AsEnumerable();
return pinData.Select(item => new MapPin
{
Id = item.EnumerationCentre.EnumerationCentreUid.ToString(),
Name = item.Person.FullName,
FillColour = GetMapPinColour(item, model),
Latitude = item.EnumerationCentre.Location.Latitude,
Longitude = item.EnumerationCentre.Location.Longitude,
Count = item.IssuedVoucherCollection.Count()
});
我尝试过使用yield return而不是select,但OutOfMemoryException是使用Select函数抛出的。
我已经完成了一些谷歌搜索,但还是看不出我还能尝试什么。
答案 0 :(得分:1)
您当前的解决方案仍然存在同样的问题,因为在返回之前您收集并将所有数据存储在内存流中
您可以通过以下方式尝试:
public ActionResult RobotsText() {
Response.ContentType = "application/json";
Response.Write("[");
foreach(var item in Items)
{
Response.Write(JsonSerializer.Serialize(item));
if ( /*not last*/)
{
Response.Write(",");
}
}
Response.Write("]");
return new EmptyResult();
}