处理大文本(JSON)文件

时间:2018-06-27 11:30:52

标签: c# sql json excel

我需要允许Intranet .NET Web门户用户将自由文本SQL查询发送到后端(SQL Server 2014上的只读数据库)并在Excel中获取结果,但是在大多数情况下,这种方法都可以正常工作但是当结果太大(大约350mb,250k记录)而无法处理时,代码将失败。

我的第一个尝试是直接将结果作为JSON序列化到前端的数据表中。

之所以失败,是因为遍历结果集会抛出System.OutOfMemoryException

private JavaScriptSerializer _serializer;
return _serializer.Serialize(results));

因此决定直接在界面上显示此结果数量不是一件好事,因为IE会遇到困难。因此选择了提示用户通过将结果保存到JSON文件中来下载输出的Excel副本的选项,然后读取该文件并将其转换为Excel:

using (StreamReader sr = new StreamReader(filePath))
String json;
// Read and display lines from the file until the end of 
// the file is reached.
while ((json = sr.ReadLine()) != null)
{
    Console.WriteLine(json);}
}

但是,ReadLine()方法会引发相同的异常,请注意,由于文件仅包含一行,因此ReadLine失败,否则我将尝试逐行进行迭代。 / p>

最后我尝试直接访问IEnumerable并将其写入Excel

var results = new ReportProcess().ExecuteSql(sqlQuery, out string eventMessage);
List<object> queryObjects = new List<object>();


            foreach (var result in results)
            {
                queryObjects.Add(result);
            }

            var row = queryObjects.FirstOrDefault();
            if (row != null)
            {
                var recordType = row.GetType();

                using (var excelFile = new ExcelPackage())
                {
                    MemberInfo[] membersToInclude = recordType
                        .GetProperties(BindingFlags.Instance | BindingFlags.Public)
                        .ToArray();

                    var worksheet = excelFile.Workbook.Worksheets.Add("Sheet1");

                    worksheet.Cells.LoadFromCollection(queryObjects, true,
                        OfficeOpenXml.Table.TableStyles.None,
                        BindingFlags.Instance | BindingFlags.Public,
                        membersToInclude);


                    fileName = Guid.NewGuid() + ".xlsx";
                    excelFile.SaveAs(new FileInfo(HttpContext.Current.Server.MapPath("~/temp/") + fileName));

                }
            }

代码再次失败

foreach (var result in results)
{
   queryObjects.Add(result);
}

有同样的例外

因此,现在我陷入了一个事实,即无论我尝试执行什么操作来遍历IEnumerable结果,我总是会遇到OutOfMemory异常。

我还尝试通过将gcAllowVeryLargeObjects中的web.config设置为true来增加分配给对象的内存,但无济于事:

 <runtime>
    <gcAllowVeryLargeObjects enabled="true"/>
 </runtime>

其他尝试:

enter image description here

Google搜索没有带来任何解决问题的方法,没有任何建议/想法吗?

1 个答案:

答案 0 :(得分:0)

最终,我不得不重写代码以实现外部库,以使用CsvHelper

序列化CSV。
using (StreamReader sr = new StreamReader(filePath))
                {
                    var csvReader = new CsvReader(sr);
                    var records = csvReader.GetRecords<object>();
                    var result = string.Empty;
                    try
                    {
                        return JsonConvert.SerializeObject(new ServerData(records, _eventMessage));
                    }
                    catch (Exception ex)
                    {
                        _eventMessage.Level = EventMessage.EventLevel.Error;
                    }


                    return _serializer.Serialize(new ServerData(result, _eventMessage));
                }

这似乎适用于大型数据集,OutOfMemory不再出现异常