处理大型存储过程结果

时间:2018-11-28 14:10:40

标签: c# entity-framework

所以我正在研究每天运行一次的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万个对象?

1 个答案:

答案 0 :(得分:5)

在这种情况下,最好的选择是尝试使用非缓冲的读取器API,这样就无需一次将所有对象都缓冲在内存中。我不知道context.GetArt()会返回什么,但是如果已经 IEnumerable<T>,那么您已经可以访问它了。然后,您可以遍历该数据(foreach)以执行所需的任何操作,而不必一次将所有数据都存储在内存中。如果GetArt()方法 不提供此功能:则可以使用其他API。例如,使用“ dapper”可以Query<T>指定可选的buffered: false参数(默认为true,因为在大多数情况下都可以使用)。

但是请注意,这里的关键点是:您不能将它们放入List<T>中。当您这样做时-它需要缓冲。同样,OrderBy之类的操作(应用于序列而不是查询时):会导致缓冲。