Можно ли вставить большой объем данных, используя linq-to-sql? - PullRequest
3 голосов
/ 14 июля 2010

Мне нужно вставить большой объем данных в SqlServer 2008. Мой проект основан на linq-to-sql.

Я обрабатываю CSV-файл с 100 000 строк. Каждая строка отображается на Order объект. Order содержит также коллекцию объектов Category и Code. Мне нужно сопоставить каждую строку с объектом, чтобы проверить его.

Затем мне нужно вставить все эти объекты в базу данных.

List<Order> orders = Import("test.csv");
db.Orders.InsertAllOnSubmit(orders);
db.SubmitChanges();

OR

foreach(Order order in orders)
db.Orders.InsertOnSubmit(order);
db.SubmitChanges();

Оба пути медленные. Есть ли обходной путь? Я могу использовать другой подход, чем l2sql для этой задачи.

Я читал о классе SqlBulkCopy - будет ли он обрабатывать вставку дочерних объектов ?

Ответы [ 4 ]

2 голосов
/ 14 июля 2010

Попробуйте использовать транзакции меньшего размера.

foreach(List<Order> orderbatch in orders.Batch(100))
{
  db.Orders.InsertOnSubmit(orderbatch); 
  db.SubmitChanges();   
}


public static IEnumerable<List<T>> Batch<T>(this IEnumerable<T> source, int batchAmount)
{
  List<T> result = new List<T>();
  foreach(T t in source)
  {
    result.Add(t);
    if (result.Count == batchSize)
    {
      yield return result;
      result = new List<T>();
    }
  }
  if (result.Any())
  {
    yield return result;
  }
}
2 голосов
/ 14 июля 2010

Как отмечает @Brian, LINQ to SQL не выполняет массовую вставку, но этот блог говорит о том, чтобы заставить его работать.

Автор, кажется, добавил код с тех пор, как я впервые его прочитал (это с 2008 года).

0 голосов
/ 14 июля 2010

Я думаю, что лучше вставлять объекты по группам, например, с 1000 объектами, а затем располагать сеанс.

Производительность здесь сбалансирована между двумя краями: чрезмерное использование памяти, вызванное хранением всех 100 000 объектов водна сторона, и время для создания сеанса и повторного подключения базы данных на другой стороне.

Кстати, нет существенной разницы между сеансом. InsertAllOnSubmit (данные) и foreach (переменные в данных)).

0 голосов
/ 14 июля 2010

Этот CSV-ридер был очень быстр для меня: http://www.codeproject.com/KB/database/CsvReader.aspx

Но да, операция массового копирования, использующая только SQL Server, будет быстрее, если у вас есть возможность.

LINQ to SQL не имеет возможности массового обновления, о которой я знаю ... вы должны выполнять итерацию.

НТН.

...