是否可以使用linq-to-sql插入大量数据?

问题描述:

我需要将大量数据插入到SqlServer 2008中。我的项目基于linq-to-sql。是否可以使用linq-to-sql插入大量数据?

我用100.000行处理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类 - 它会处理插入子实体以及?

尝试使用较小的交易。

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

如果你打算使用这种解决方案,你可以试着按聚集索引进行排序。如果您没有插入每批可能会重新排序所有以前的行。或者它可能不是,但这是你需要注意的事情。 – 2010-07-14 15:00:39

+0

@Mike两页分裂与热点...一如既往 - 衡量,衡量,衡量。 – 2010-07-14 16:43:42

+0

我接受了这个答案。然而EntityFramework的速度要快几倍。另一方面,我应该使用SqlBulkCopy,但它不处理子实体。 – jlp 2010-08-04 08:48:44

这个CSV阅读器是真的快给我:http://www.codeproject.com/KB/database/CsvReader.aspx

但是,是的,如果你可以选择只使用SQL Server的批量复制操作会更快。

LINQ to SQL没有批量更新功能,我知道...你必须迭代。

HTH。

+0

我使用CsvReader来读取csv文件并映射到对象。主要问题是如何快速将100.000个对象插入数据库。 – jlp 2010-07-14 14:24:31

+0

用于批量插入的sql工具是最好的,使用sqlbulkcopy或使用SSIS导入,也有批量工具。工作非常快。 – 2010-07-14 16:39:20

As @Brian指出,LINQ to SQL不会执行批量插入,但this blog谈到了离开它来工作。

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

+0

我试过了,它工作的很快,但它不插入子实体。 – jlp 2010-07-15 09:43:58

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

此处的性能在两个边缘之间保持平衡:一边保存所有100,000个对象在内存中导致的内存过度使用,以及在另一边创建会话和重新连接数据库的时间。

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