我已经实现了一个应用程序,它从csv文件中获取数据并插入到Sql DB中,我使用Linq到sql。我也有要求skipping那些有一些验证的记录, 达到此目的我使用了一个循环,并在循环内调用submitchnages()。批量从csv插入到数据库使用Linq到sql
问题:此应用程序的记录数量较少(< 100),但实际上不适合获取更多3 - 4个记录的csv文件。我只是简单地运行我的应用程序对这些大文件,结果应用程序需要很长时间(5 - 6小时)。
请提出任何更好的方法。
我已经实现了一个应用程序,它从csv文件中获取数据并插入到Sql DB中,我使用Linq到sql。我也有要求skipping那些有一些验证的记录, 达到此目的我使用了一个循环,并在循环内调用submitchnages()。批量从csv插入到数据库使用Linq到sql
问题:此应用程序的记录数量较少(< 100),但实际上不适合获取更多3 - 4个记录的csv文件。我只是简单地运行我的应用程序对这些大文件,结果应用程序需要很长时间(5 - 6小时)。
请提出任何更好的方法。
Linq-to-SQL非常适合获取数据库的数据,或者一次性验证和少量插入/更新。但是对于你正在做的事情(ETL),听起来像你需要查看SqlBulkCopy
对象。继续使用你的L2S对象来进行验证,但是不要提交更改,只需将对象映射到一个好的旧式ADO.NET DataTable中,并且每隔1000条记录就可以批量插入它们。
提及'SqlBulkCopy'。 – Steven 2011-05-07 15:02:53
如果性能是一个大问题,LINQ to SQL可能不是这项工作的工具。然而,折腾的LINQ to SQL出你的解决方案的大门之前,你可能会考虑以下几点:
DataContext
。 DataContext
缓存所有发送到数据库并从数据库中检索的实体,这将导致大量内存占用并最终...内存不足。批量插入是O/RM不擅长的事情,所以您可能需要采取不同的方法。
如果您必须使用Linq2Sql进行插入操作,则可能需要进行间歇性提交。像这样 -
public void LoadLargeDataUsingLinqToSql(string pathToCSV){
DataTable dt = LoadMyCSVToDataTable(pathToCSV);
int myPerformanceCounter = 0;
foreach(DataRow dr in dt.Rows()){
MyLinqClass m = ConvertDRToMyLinqClass(dr);
if(m.IsValidAndReadyToBeSaved()){
MyDataContext.MyLinqClassRef.InsertOnSubmit(m);
myPerformanceCounter++;
}
if(myPerformaceCounter>25000){
//Commit to clear cache.
MyDataContext.SubmitChanges();
myPerformanceCounter=0;
}
}
//Commit leftovers
MyDataContext.SubmitChanges();
}
'SubmitChanges'不清除'DataContext'的内部缓存。它将坚持所有的对象,甚至提交一次。你应该在调用'SubmitChanges()'后创建一个新的'DataContext'。 – Steven 2011-05-07 15:02:00
按缓存我并不是指DataContext缓存。我的意思是等待提交给数据库的对象的逻辑缓存。创建新的数据环境并不总是可行的,除非你有一个非常严格的“工作单元”实现。 SQLBulk副本是典型数据加载程序的首选方法,但如果您想坚持纯粹的基于对象的模型,那么这种方法可以正常工作。在一分钟内插入几十万个物体。 – YetAnotherUser 2011-05-07 17:40:23
请参阅http://blogs.msdn.com/b/dinesh.kulkarni/archive/2008/07/01/linq-to-sql-tips-9-understanding-datacontext-s-internal-caching.aspx。 L2S缓存不是一个非常昂贵的缓存。 – YetAnotherUser 2011-05-07 17:43:47
发布相关的代码? – 2011-05-06 22:34:31