所以我正在研究每天运行一次的Windows服务。该服务用于将外部数据库中的数据合并到我的数据库中。问题是我只能使用存储过程访问外部数据库。
当我使用这些存储过程之一时,它将返回120万个对象,并且我的服务的ram使用量上升到2.5GB。
仅供参考:我先将EF 6与DB一起用于外部数据库,并将代码首先用于我的datbase。
以下方法中的GetArt()是实体框架创建的存储过程之一,它返回120万个对象。
public List<GetArt_Result> GetArtls()
{
List<GetArt_Result> results = new List<GetArt_Result>();
using (ExternalContext context = new ExternalContext()) {
results = context.GetArt().ToList();
}
return results;
}
public void SaveArticles(List<GetArt_Result> externalArtls)
{
try {
List<Article> artls = new List<Article>();
foreach (var artl in externalArtls) {
artls.Add(new Article(artl));
}
using (DbContext context = new DbContext()) {
context.BulkInsert(artls);
}
} catch (Exception ex) {
throw ex;
}
}
我的问题:如何在不使用高内存的情况下处理120万个对象?
答案 0 :(得分:5)
在这种情况下,最好的选择是尝试使用非缓冲的读取器API,这样就无需一次将所有对象都缓冲在内存中。我不知道context.GetArt()
会返回什么,但是如果已经 IEnumerable<T>
,那么您已经可以访问它了。然后,您可以遍历该数据(foreach
)以执行所需的任何操作,而不必一次将所有数据都存储在内存中。如果GetArt()
方法 不提供此功能:则可以使用其他API。例如,使用“ dapper”可以Query<T>
指定可选的buffered: false
参数(默认为true
,因为在大多数情况下都可以使用)。
但是请注意,这里的关键点是:您不能将它们放入List<T>
中。当您这样做时-它需要缓冲。同样,OrderBy
之类的操作(应用于序列而不是查询时):会导致缓冲。