Как лучше всего использовать метод .SaveChanges() в службах данных ADO.Net?

StackOverflow https://stackoverflow.com/questions/190066

Вопрос

Есть ли у кого-нибудь полезная информация об использовании метода .SaveChanges()?

Я испытываю различные проблемы при попытке использовать метод .SaveChanges() для моего объекта контекста данных.Я беру данные из существующего источника данных, создаю соответствующие объекты EntityFramework/DataService, заполняю эти созданные объекты данными, добавляю эти объекты в контекст и затем сохраняю эти данные, вызывая .SaveChanges.

Сценарии, которые я придумал (и проблемы, связанные с ними), таковы...В каждом сценарии у меня есть цикл foreach, который берет данные из строк в DataTable и генерирует объекты, прикрепляя их к контексту по мере их поступления.(примечание:три объекта (член) и два «адреса», которые прикрепляются через вызов SetLink) — по сути, это инструмент преобразования, позволяющий брать данные из одного хранилища данных и помещать их в хранилище данных, предоставляемое службами данных.

  • Вызовите .SaveChanges() без каких-либо параметров один раз в конце цикла foreach (т.е.вне цикла)
    • Ошибка OutOfMemory примерно на 1/3 пути (30 000 из 90 000 сохранений) - не знаю, как это происходит, хотя, поскольку каждый элемент сохранения представляет собой отдельный вызов SQL к базе данных, на чем может не хватить памяти?
  • Вызов .SaveChanges() без каких-либо параметров один раз за цикл.
    • Это работает, но занимает абсолютно вечность (8 часов на 90 000 сохранений)
  • Вызовите .SaveChanges(SaveChangesOption.Batch) один раз в конце цикла foreach.
    • Та же ошибка OutOfMemory, но без сохранения в базу данных.
  • Вызовите .SaveChanges(SaveChangesOption.Batch) один раз за цикл.
    • 404 ошибка не найдена
  • Вызов .SaveChanges(SaveChangesOption.Batch) один раз за 10 циклов.
    • Ошибка 400 Bad Request (иногда)
    • OutOfMemory после нескольких итераций
  • Несколько случайных попыток создать контекст один раз за цикл, использовать его как переменную в начале цикла или сделать его доступной частной переменной-членом.
    • Разные результаты, не поддающиеся количественной оценке, ни один из них не настолько хорош

Каков предпочтительный метод вызова .SaveChanges() из клиентского объекта при такой большой загрузке данных?Есть ли что-то, что я не понимаю в том, как работает .SaveChanges()?Может ли кто-нибудь предоставить более подробную информацию о том, как следует использовать эту функцию и каковы (если таковые имеются) ограничения на сохранение данных через службы данных?Существуют ли какие-либо рекомендации по вызову метода .SaveChanges()?Есть ли какая-нибудь особенно хорошая документация по вызову метода .SaveChanges()?

Это было полезно?

Решение

У меня нет большого опыта использования EntityFramework (просто случайный эксперимент). Пробовали ли вы вызывать .SaveChanges() каждые n итераций?

Я имею в виду что-то вроде этого:

int i = 0;
foreach (var item in collection)
{
    // do something with your data
    if ((i++ % 10) == 0)
        context.SaveChanges();
}
context.SaveChanges();

Я знаю, что это некрасиво, но это первое возможное решение, которое я придумал.

Другие советы

Я также использую EntityFramework в небольшом проекте, поэтому меня тоже очень интересует этот вопрос.Два быстрых вопроса:Вы пытались отключить кеширование объектов данных в контексте данных?Вы пытались закрыть контекст данных и создать новый во время цикла, чтобы освободить память?

С уважением

Кеннет

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top