Обработка больших результатов хранимых процедур - PullRequest
0 голосов
/ 28 ноября 2018

Итак, я работаю над службой Windows, которая запускается один раз в день.Служба для слияния данных из внешней базы данных в мою базу данных.Проблема в том, что у меня есть доступ только к внешней базе данных с хранимыми процедурами.

Когда я использую одну из этих хранимых процедур, она возвращает 1,2 миллиона объектов, а использование моей оперативной памяти возрастает до 2,5 ГБ.

К вашему сведению: сначала я использую EF 6 с БД для внешней базы данных, а сначала код для моей базы данных.

GetArt () в следующем методе является одной из хранимых процедур, которые сущностьФреймворк создан, и он возвращает 1,2 миллиона объектов.

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;
        }
    }

Мой вопрос: Как я могу обрабатывать 1,2 миллиона объектов без использования большого количества оперативной памяти?

1 Ответ

0 голосов
/ 28 ноября 2018

В этом сценарии лучше всего попытаться использовать API-интерфейс для чтения без буферизации, чтобы вам не нужно было буферизовать все объекты в памяти одновременно.Я не знаю, что context.GetArt() возвращает, но если это уже IEnumerable<T>, то возможно , что у вас уже есть доступ к этому;затем вы можете перебрать эти данные (foreach), чтобы сделать все, что вам нужно, без необходимости хранить все данные в памяти одновременно.Если метод GetArt() не обеспечивает это: тогда может быть возможно использовать альтернативный API.Например, для «dapper» это может быть Query<T>, указывающий необязательный параметр buffered: false (по умолчанию true, так как это подходит для большинства случаев использования).

Обратите внимание, однако, чтоключевой момент здесь: вы не можете бросить их в List<T>.В тот момент, когда вы это делаете - это требует буферизации.Аналогично, операции типа OrderBy (применительно к последовательностям, а не к запросам): вызывает буферизацию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...