1

csvファイルをアップロードするためのアップロードボタンがあるWebフォームがある場合、コードはファイルを解析し、解析されたデータを使用して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);
                    }
4

4 に答える 4

1

KBCsvを使用します。1 秒あたり 40K 行が解析され、1 秒あたり 70K+ 行がスキップされています。これは私が見た中で最速です。また、かなり安定しています。次に、上記のように SQL を手動で生成します。データをリロードしてパフォーマンスを向上させる場合は、マルチスレッドでトランザクションなしで実行します (MS SQL のみ)。データベース サーバーへのネットワーク帯域幅に応じて、1 秒あたり最大 10,000 行のインポート速度を得ることができます。

解析しないでくださいDataTable- 非常に遅いです。

于 2012-11-01T02:01:29.943 に答える
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();
于 2012-11-01T11:08:15.643 に答える
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

于 2012-10-31T23:50:30.050 に答える
0

本当に答えではありませんが、コメントとして投稿するには長すぎます...

解析された値 ( など) を破棄しているように見えるmemnbrため、csv 解析コードを次のように大幅に削減できます。

return 
 File
   .ReadLines(filename)
   .Skip(1)
   .Select(line => line.Split(','))
   .ToList();
于 2012-10-31T23:54:45.617 に答える