.net 读取文件并写入数据库
昨天在一次面试中,我被问到这个问题,我提供的答案似乎没有给面试官留下深刻印象( 以下是场景…文件在新行分隔的记录中具有逗号分隔的属性值。要求该文件必须进入具有匹配列序列的数据库表中。该文件有一个自引用列,即一列“Id”包含该记录的唯一非空Id,另一列“LinkId”它包含其他记录的id。此值可以为空 要求:文件必须以相同的顺序插入数据库,但必须同时插入所有文件!这意味着不能多次插入 问题:如何在.Net框架中最好地实现这一点(您可以使用最新的4.0框架) 我给出的解决方案是:逐行读取文件并将其解析为所需的XML,然后使用DataTable.ReadXML()调用立即将文件加载到数据表中,并提交保存该数据表的数据集 挑战: 一个100 GB的文本文件怎么样?它会这样工作吗?功能会变得多慢?如果我们必须将一个XML保存到内存中存储100 GB的数据,系统的虚拟地址空间会支持它吗?页面交换不会导致问题并变得慢 DataTable.ReadXML()是否适用于如此庞大的XML?dataset是否能够提交 我的回答是:-/ 有什么想法吗,伙计们 Thx.net 读取文件并写入数据库,.net,xml,memory-management,datatable,.net,Xml,Memory Management,Datatable,昨天在一次面试中,我被问到这个问题,我提供的答案似乎没有给面试官留下深刻印象( 以下是场景…文件在新行分隔的记录中具有逗号分隔的属性值。要求该文件必须进入具有匹配列序列的数据库表中。该文件有一个自引用列,即一列“Id”包含该记录的唯一非空Id,另一列“LinkId”它包含其他记录的id。此值可以为空 要求:文件必须以相同的顺序插入数据库,但必须同时插入所有文件!这意味着不能多次插入 问题:如何在.Net框架中最好地实现这一点(您可以使用最新的4.0框架) 我给出的解决方案是:逐行读取文件并将其解
Harish。显然,您可以使用OLEDB打开CSV文件,从那里可以轻松地从一个数据库到另一个数据库获取数据
我不确定它是否真的解决了内存问题,但它比在内存中构建XML副本要好得多。如果您使用的是SQL Server,可以使用BULK INSERT命令 基本上,您可以设置一个SQLCommand对象,将CommandText设置为:
sqlCommand.CommandText = "BULK INSERT " & tableName & " FROM '" & file & "' WITH(TABLOCK, FIELDTERMINATOR=',')
sqlCommand.ExecuteNonQuery()
tableName—要插入的表的名称。文件-是您希望SQL Server读取的文件的名称。您需要确保SQL Server能够访问文件的存储位置。这包括ACL权限和网络连接
大容量插入命令有很多选项,我在过去使用过,效果非常好。不管怎样,您都将有多个插入。如果文件不是太大,最简单的方法是先创建一个数据库事务,然后逐行读取,然后每行创建一个插入命令。一旦所有行都被读取,您可以提交事务 对于一个100GB的文本文件,我会首先将它分成更小的块进行插入。也许每1000行提交一次事务 “Id”和“LinkId”字段在我看来像是一种典型的父项>子项关系。因此,只要先插入父项,就不会出现问题 您没有提到这将是什么类型的数据库,但是如果是MSSQL,那么您还可以使用Linq to Sql在每行创建一个新对象并将其添加到列表中。假设您使用的是C#,那么您可以使用:
List<YourObject> YourList = new List<YourObject>();
using(System.IO.StreamReader file = new System.IO.StreamReader("C:\yourstorage.txt")) {
while((line = file.ReadLine()) != null) {
string[] fields = line.Split(',');
YourObject obj = new YourObject();
obj.FieldX = fields[0];
obj.FieldY = fields[1];
obj.FieldZ = fields[2];
YourList.Add(obj);
}
}
using(YourDataContext db = new YourDataContext()) {
db.YourObjects.InsertAllOnSubmit(YourList);
db.SubmitChanges();
}
List YourList=新列表();
使用(System.IO.StreamReader file=new System.IO.StreamReader(“C:\yourstorage.txt”)){
而((line=file.ReadLine())!=null){
string[]fields=line.Split(',');
YourObject obj=新建YourObject();
obj.FieldX=字段[0];
obj.FieldY=字段[1];
obj.FieldZ=字段[2];
添加(obj);
}
}
使用(YourDataContext db=newyourdatacontext()){
db.YourObjects.InsertAllOnSubmit(YourList);
db.SubmitChanges();
}
其中,YourObject是已经添加到项目中的Linq to Sql模型,YourObjects是数据库中的实际表名。但是对于一个大文件来说,这可能会占用大量内存。对不起,不确定是否有与Oracle等效的表名。我快速搜索了一下,发现了这个表名,其中提到了一个叫做Sql Loader实用程序的东西,我从来没有用过它,所以我不能对它发表评论。是的,它是SQL加载器。:)太棒了!这也支持Linq到Oracle模型吗?应该支持,但在这种情况下,您需要使用特定于Oracle的提供程序。也就是说,还是上面的那个。但这些都是实验性的,会增加一些复杂性,所以每几千行的原始事务、命令和插入可能会更好。