我需要在SqlServer 2008中插入大量数据。我的项目基于linq-to-sql。
我处理100.000行的csv文件。每行都映射到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类的内容 - 它是否会处理插入子实体?
答案 0 :(得分:2)
正如@Brian所指出的,LINQ to SQL不会进行批量插入,但是this blog会讨论它以使其工作。
自从我第一次阅读以来,作者似乎已经添加了代码(从2008年开始)。
答案 1 :(得分: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;
}
}
答案 2 :(得分:0)
这个CSV阅读器对我来说非常快:http://www.codeproject.com/KB/database/CsvReader.aspx
但是,如果您可以选择使用SQL Server,那么批量复制操作会更快。
LINQ to SQL没有我知道的批量更新功能......你必须遍历。
HTH。
答案 3 :(得分:0)
我认为最好按组插入对象,例如1000个对象,然后处置会话。
这里的性能在两个边缘之间是平衡的:内存过度使用是由于将所有100,000个对象保留在内存中的一侧,以及创建会话和在另一侧重新连接数据库的时间。
顺便说一下,session.InsertAllOnSubmit(data)和foreach(var i in data)session.Insert(i)。
之间没有显着差异。