问题描述
Hi,各位大神,想实现这样一个逻辑,假设:文件夹内有10个txt文本文档,里面每个对应一个sql内的表,且每个文本文档(以及sql中的表)列数均不同。这边我读取了每个txt的路径。然后每个字段用"|"符号隔开。我想实现每个txt文本文件自动匹配sql里的表,且列也自动匹配,而不是写10个case.每个case需要写几十个columns.add.放在datatable中。有什么好办法吗?privatevoidbutton1_Click(objectsender,EventArgse){DataTabledt=newDataTable();//dt.Columns.Add("a");//dt.Columns.Add("b");//dt.Columns.Add("c");//dt.Columns.Add("d");foreach(stringfilenameinDirectory.GetFiles("D:\InstinctData","*.txt",SearchOption.AllDirectories)){Console.WriteLine(filename);stringstrFilePath=filename;FileStreamfs=newFileStream(strFilePath,FileMode.Open,FileAccess.Read);StreamReadersr=newStreamReader(fs,System.Text.Encoding.Unicode);SqlConnectionconn=newSqlConnection();conn.ConnectionString="DataSource=.;Database=~;Uid=~;Pwd=~";conn.Open();stringstrLine=sr.ReadLine();while(strLine!=null){string[]strArray=newstring[4];strArray=strLine.Split('|');DataRowdr=dt.NewRow();dr[0]=strArray[0];dr[1]=strArray[1];dr[2]=strArray[2];dr[3]=strArray[3];stringsql="insertintoA_Testvalues('"+dr[0]+"','"+dr[1]+"','"+dr[2]+"','"+dr[3]+"')";SqlCommandcmd=newSqlCommand(sql,conn);cmd.ExecuteNonQuery();dt.Rows.Add(dr);strLine=sr.ReadLine();}sr.Close();fs.Close();conn.Close();//stringfilecontent=string.Join("rn",System.IO.File.ReadAllLines(filename));//Console.WriteLine(filecontent);}}求大神给点小代码启发一下。因为这边是insert语句,必须注明列的。。。很困难。或者先把sql表中的列读取到gridview中?然后循环列写在insert语句中??我这边假设有100个columns怎么办?谢谢
解决方案
解决方案二:
省掉你的DataTable,这样就不用纠结了。可以直接写数据库或者建一个Model来承载你的数据。
解决方案三:
引用1楼D56233577的回复:
省掉你的DataTable,这样就不用纠结了。可以直接写数据库或者建一个Model来承载你的数据。
再给点提示吧,比如用什么model,怎么写数据库,谢谢
解决方案四:
如果你txt的文件名包含表名,那么表就能匹配了,如果你txt内容的第一行存字段名,那么列也能匹配。不管多少列,用一个循环来建DataTable,不需要case。
解决方案五:
1、CSVHelper读取成实体集合(看你这描述txt数据格式就是csv格式)2、ORM映射3、循环插入数据库其实说白了就是怎么读,然后ORM怎么来做插入数据库的事情如果txt数据量很大,但要求读取时间又很短的话,那还真必须DataTable,然后通过SqlBulkCopy插入数据库
解决方案六:
引用4楼starfd的回复:
1、CSVHelper读取成实体集合(看你这描述txt数据格式就是csv格式)2、ORM映射3、循环插入数据库其实说白了就是怎么读,然后ORM怎么来做插入数据库的事情如果txt数据量很大,但要求读取时间又很短的话,那还真必须DataTable,然后通过SqlBulkCopy插入数据库
太难了。。。
解决方案七:
引用3楼D56233577的回复:
如果你txt的文件名包含表名,那么表就能匹配了,如果你txt内容的第一行存字段名,那么列也能匹配。不管多少列,用一个循环来建DataTable,不需要case。
能不能给点代码,循环建datatable.谢谢
解决方案八:
用datatable的话表数据量太大很容易内存溢出数据文件要包含表名,数据流方法如下:intiBufferSize=10240;//10mbbyte[]buffer=newbyte[iBufferSize];using(FileStreamstream=newFileStream(argument.FullPath,FileMode.Open,FileAccess.Read)){StreamReaderfileReader=newStreamReader(stream);longiFileSize=stream.Length;intiTotalCount=(int)Math.Ceiling((double)(iFileSize/iBufferSize));string[]strRows;string[]strCells;stringtmpHalfRow="";DataRowdr;intreadBytes;while((readBytes=stream.Read(buffer,0,iBufferSize))>0){stringxx=tmpHalfRow+Encoding.Default.GetString(buffer);strRows=xx.Replace("n","#").Split('#');for(inti=0;i<strRows.Length;i++){if(i==strRows.Length-1){tmpHalfRow=strRows[i];continue;}strCells=strRows[i].Split('|');dr=dt.NewRow();for(intj=0;j<strCells.Length-1;j++){dr[j]=strCells[j];}dt.Rows.Add(dr);}if(dt.Rows.Count>20000||readBytes<iBufferSize){ExportToExcel(dt,rowHeight,splitTimes,outPutName,styleList);dt.Clear();GC.Collect();splitTimes++;}}
解决方案九:
引用4楼starfd的回复:
1、CSVHelper读取成实体集合(看你这描述txt数据格式就是csv格式)2、ORM映射3、循环插入数据库其实说白了就是怎么读,然后ORM怎么来做插入数据库的事情如果txt数据量很大,但要求读取时间又很短的话,那还真必须DataTable,然后通过SqlBulkCopy插入数据库
另外我想到个问题,如果进去datatable都是string形式,那么sqlbulkcopy到数据库表中,可否自动匹配不同的类型,因为表中有很多类型,intnvarchardatetimemoney等等
解决方案十:
sqlbulkcopy是看你的datatable的列类型是否一致的
解决方案十一:
你全部string进去肯定要错的