.net 读取文件并写入数据库

.net 读取文件并写入数据库,.net,xml,memory-management,datatable,.net,Xml,Memory Management,Datatable,昨天在一次面试中,我被问到这个问题,我提供的答案似乎没有给面试官留下深刻印象( 以下是场景…文件在新行分隔的记录中具有逗号分隔的属性值。要求该文件必须进入具有匹配列序列的数据库表中。该文件有一个自引用列,即一列“Id”包含该记录的唯一非空Id,另一列“LinkId”它包含其他记录的id。此值可以为空 要求:文件必须以相同的顺序插入数据库,但必须同时插入所有文件!这意味着不能多次插入 问题:如何在.Net框架中最好地实现这一点(您可以使用最新的4.0框架) 我给出的解决方案是:逐行读取文件并将其解

昨天在一次面试中,我被问到这个问题,我提供的答案似乎没有给面试官留下深刻印象(

以下是场景…文件在新行分隔的记录中具有逗号分隔的属性值。要求该文件必须进入具有匹配列序列的数据库表中。该文件有一个自引用列,即一列“Id”包含该记录的唯一非空Id,另一列“LinkId”它包含其他记录的id。此值可以为空

要求:文件必须以相同的顺序插入数据库,但必须同时插入所有文件!这意味着不能多次插入

问题:如何在.Net框架中最好地实现这一点(您可以使用最新的4.0框架)

我给出的解决方案是:逐行读取文件并将其解析为所需的XML,然后使用DataTable.ReadXML()调用立即将文件加载到数据表中,并提交保存该数据表的数据集

挑战:

一个100 GB的文本文件怎么样?它会这样工作吗?功能会变得多慢?如果我们必须将一个XML保存到内存中存储100 GB的数据,系统的虚拟地址空间会支持它吗?页面交换不会导致问题并变得慢

DataTable.ReadXML()是否适用于如此庞大的XML?dataset是否能够提交

我的回答是:-/

有什么想法吗,伙计们

Thx
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的提供程序。也就是说,还是上面的那个。但这些都是实验性的,会增加一些复杂性,所以每几千行的原始事务、命令和插入可能会更好。