有一个webform,它有一个上传按钮来上传csv文件,然后我的代码需要解析文件并使用解析后的数据插入到SQL表中。我正在为分析数据解析数据是正确的,它没有获取流读取器的文件名。这是解析数据最有效的方法吗?我应该解析成数据表吗?
protected void UploadBtn_Click(object sender, EventArgs e)
{
if (FileUpload.HasFile)
{
string filename = Path.GetFileName(FileUpload.FileName);
List<string[]> ValuesToUpload = parseData(filename);
//if (!Directory.Exists(ConfigurationManager.AppSettings["temp_dir"].ToString().Trim()))
//{
// Directory.CreateDirectory(ConfigurationManager.AppSettings["temp_dir"].ToString().Trim());
//}
//FileUpload.SaveAs(ConfigurationManager.AppSettings["temp_dir"].ToString().Trim() + filename);
//using (FileStream stream = new FileStream(ConfigurationManager.AppSettings["temp_dir"].ToString().Trim() + filename, FileMode.Open, FileAccess.Read, FileShare.Read))
}
}
public List<string[]> parseData(filename)
{
int j=0;
List <string[]> members = new List<string[]>();
try
{
using (StreamReader read = new StreamReader(filename))
{
while (!read.EndOfStream)
{
string line = read.ReadLine();
string[] values = line.Split(',');
if(j==0)
{
j++;
continue;
}
long memnbr = Convert.ToInt64(values[0]);
int loannbr = Convert.ToInt32(values[1]);
int propval = Convert.ToInt32(values[2]);
members.Add(values);
}
答案 0 :(得分:1)
使用KBCsv。我们每秒解析40K行,每秒跳过70K +行。这是我见过的最快的。而且还很稳定。然后按照上面的建议手动生成SQL。如果执行数据重新加载并以性能为目标,则运行多线程,无事务(仅限MS SQL)。每秒最多可以获得10K行的导入速度,具体取决于您对数据库服务器的网络带宽。
不要解析为DataTable
- 它非常慢。
答案 1 :(得分:0)
由于您要将数据插入SQL表,我首先创建一个表示表的类,并为每个记录创建一个新对象。 (这是为了能见度)。
或者我可以使用以下方法(假设您正在使用MS SQL Server) 1.动态插入查询
StringBuilder strInsertValues = new StringBuilder("VALUES");
your ParsingCode HERE..
string [] values = line.Split(',');
strInsertValues.AppendFormat("({0},{1},{2}),", values[0], values[1], values[2]);
end parse
using(SqlConnection cn = new SqlConnection(YOUR_CONNECTION_STRING)){
SqlCommand cmd = cn.CreateCommand;
cmd.CommandType = SqlCommandType.Text;
cmd.CommandText = "INSERT INTO TABLE(Column1, Column2, Column3) " + strInsertValues.ToString().SubString(0, strInsertValues.Length);
cn.Open();
cmd.ExecuteNonQuery();
}
2。使用BulkCopy(推荐) 创建一个表示CSV值的DataSet 为每个解析的行添加新记录 为DataSet和SQL表创建列映射, 使用BulkCopy对象插入数据。 参考BulkCopy:http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlbulkcopy.aspx
答案 2 :(得分:0)
不是一个真正的答案,但发表评论的时间太长......
因为看起来你丢弃了解析后的值(memnbr
等...),你可以大大减少你的csv解析代码:
return
File
.ReadLines(filename)
.Skip(1)
.Select(line => line.Split(','))
.ToList();
答案 3 :(得分:0)
以下代码示例将批量插入CSV数据到具有匹配列的登台表中,然后执行存储过程以规范化服务器上的数据。
这比手动解析数据和逐行插入数据要有效得多。几个月前,我使用类似的代码向我们的数据库提交1,500,000多条记录,并在几秒钟内对数据进行标准化。
var sqlConnection = new SqlConnection(DbConnectionStringInternal);
// Bulk-import our unnormalized data from the .csv file into a staging table
var inputFileConnectionString = String.Format("Driver={{Microsoft Text Driver (*.txt; *.csv)}};Extensions=csv;Readonly=True;Dbq={0}", Path.GetDirectoryName(csvFilePath));
using (var inputFileConnection = new OdbcConnection(inputFileConnectionString))
{
inputFileConnection.Open();
var selectCommandText = String.Format("SELECT * FROM {0}", Path.GetFileName(csvFilePath));
var selectCommand = new OdbcCommand(selectCommandText, inputFileConnection);
var inputDataReader = selectCommand.ExecuteReader(CommandBehavior.CloseConnection);
var sqlBulkCopy = new SqlBulkCopy(sqlConnection) { DestinationTableName = "Data_Staging" };
if (sqlConnection.State != ConnectionState.Open)
sqlConnection.Open();
sqlBulkCopy.WriteToServer(inputDataReader);
}
// Run a stored-procedure to normalize the data in the staging table, then efficiently move it across to the "real" tables.
var addDataFromStagingTable = String.Format("EXEC SP_AddDataFromStagingTable");
if (sqlConnection.State != ConnectionState.Open)
sqlConnection.Open();
using (var addToStagingTableCommand = new SqlCommand(addDataFromStagingTable, sqlConnection) { CommandTimeout = 60 * 20 })
addToStagingTableCommand.ExecuteNonQuery();
sqlConnection.Close();