C# 从Api返回CSV,而不将所有数据库结果放入字符串中
所以我想做的是有一个api,它从一个大数据库中获取两列,并以CSV(文本)的形式返回它们。 如果我尝试先获取它们,然后构建csv,就会出现问题,因为内存很快就会填满 (800k行为400mb)。 这是我最接近于让它工作的,但格式不是真正的CSV,它是用引号分隔的行,并且不是单个字符串C# 从Api返回CSV,而不将所有数据库结果放入字符串中,c#,.net,asp.net-core,entity-framework-core,C#,.net,Asp.net Core,Entity Framework Core,所以我想做的是有一个api,它从一个大数据库中获取两列,并以CSV(文本)的形式返回它们。 如果我尝试先获取它们,然后构建csv,就会出现问题,因为内存很快就会填满 (800k行为400mb)。 这是我最接近于让它工作的,但格式不是真正的CSV,它是用引号分隔的行,并且不是单个字符串 public IEnumerable<string> getCSV() { var names = typeof(AddressBook).GetProperties()
public IEnumerable<string> getCSV()
{
var names = typeof(AddressBook).GetProperties()
.Select(property => property.Name)
.ToArray();
yield return string.Join(",", names);
foreach( string name in names)
var query = context.AddressBook.Select(x => string.Join(",", x.Name, x.Surname, x.BirthDate)).AsNoTracking();
foreach (string row in query)
{
yield return row;
}
}
public IEnumerable getCSV()
{
var name=typeof(AddressBook).GetProperties()
.Select(property=>property.Name)
.ToArray();
返回字符串。Join(“,”名称);
foreach(名称中的字符串名称)
var query=context.AddressBook.Select(x=>string.Join(“,”,x.Name,x.姓氏,x.BirthDate)).AsNoTracking();
foreach(查询中的字符串行)
{
收益返回行;
}
}
MemoryOutOfBounds
异常尝试在递归函数中使用Skip()和Take()。800K行并没有那么多,问题在于代码本身,它会生成很多临时字符串。每个子字符串操作都会产生一个新字符串。这就是为什么使用StringBuilder构造大型字符串是一个标准建议。更好的方法是,不要返回单个字符串并将它们保存在内存中,而是立即将它们写入临时文件。更好的方法是使用像CsvHelper这样的库,直接将从
foreach
循环读取的数据写入文本编写器,而不使用ToList()
。当您逐行读取数据时,您不需要Skipt()
和Take()
。因此,我获取字符串并将其写入临时文件,然后返回整个文件(假设为文件流)?上面的代码工作正常,没有太大的内存影响,但它不是真正的csv。我想我的问题是,是否存在通过api端点流式传输文本数据的选项,但我并没有尝试返回包含数据页的json对象,只是返回一个大的csv文件。在从api返回之前,您将数据保存在一个列表中。这意味着您正在内存中存储大量数据。400mb是巨大的。我知道,这是我问题的一部分。我现在的天真方法是获取所有行,将它们转换为CSV(使用字符串生成器),然后返回大字符串。但这并不好。所以我在op中尝试了这种方法,这种方法很有效,因为它不占用太多内存,而且它逐行返回,但它没有给我一个真正的csv格式。有什么办法我可以同时做到这两件事吗?