使用Linq-to-SQL是否可以插入大量数据?

3
我需要将大量数据插入SqlServer 2008。我的项目是基于linq-to-sql的。
我处理包含10万行的csv文件。每个行映射到一个Order对象,而Order还包含一组CategoryCode对象。我需要将每一行映射到一个对象以进行验证。
接下来,我需要将所有这些对象插入到数据库中。
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
尝试使用较小的交易。
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;
  }
}

如果您采用这种解决方案,最好尝试按聚集索引排序。如果不这样做,每个批次的插入可能会重新排序所有先前的行。或者可能不会,但这是您需要注意的事情。 - Mike Two
@Mike Two - 页面分割 vs 热点...像往常一样- 测量,测量,测量。 - Amy B
我接受了这个答案。但是 EntityFramework 的速度要快几倍。另一方面,我应该使用 SqlBulkCopy,但它无法处理子实体。 - jlp

2

正如 @Brian 所指出的那样,LINQ to SQL 不支持批量插入,但是这篇博客介绍了一种使其正常工作的方法。

作者似乎在我第一次阅读它时添加了代码(它来自 2008 年)。


我尝试了一下,它运行速度很快,但是它不会插入子实体。 - jlp

0

这个 CSV 读取器对我来说真的很快:http://www.codeproject.com/KB/database/CsvReader.aspx

但是,如果您有选择只使用 SQL Server 进行批量复制操作,则速度会更快。

LINQ to SQL 没有我知道的批量更新功能...您必须进行迭代操作。

希望能有所帮助。


我使用CsvReader来读取csv文件并映射到对象。主要问题是如何快速地将100,000个对象插入到数据库中。 - jlp
SQL工具进行批量插入是最好的选择,可以使用SQLBulkCopy或者使用SSIS导入,它们都有批量实用程序。速度非常快。 - Brian Mains

0

我认为最好按组插入对象,例如每组1000个对象,然后处理会话。

这里的性能在两个方面之间平衡:一方面是由于将所有10万个对象保留在内存中而导致的内存过度使用,另一方面是创建会话和重新连接数据库所需的时间。

顺便说一下,session.InsertAllOnSubmit(data)和foreach(var i in data) session.Insert(i)之间没有显着差异。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接