2016-04-06 6 views
1

誰かがMySqlを使ってトランザクションをどのように使用しているかの私のコンテキストをチェックできることを願っています。私はこれが下の概要で動作するはずだと思います。誰かが自分のコードを見て、正しく実行しているかどうか教えてください。ありがとうございました。MySQL - >トランザクションコンテキスト - >コードレビュー

私はこれがすべきと考えている:

  • は、DB接続をインスタンス化します。
  • 指定したDataTableのDataTable行を反復処理します。
  • テーブルが存在するかどうかを確認し、テーブルが存在しない場合は、テーブルの作成を実行します。
  • 新しく作成されたテーブルまたは既存のテーブルに情報のパラメータを含むInsert Commandを実行します。
  • トランザクションをコミットし、接続を閉じます。

    //Open the SQL Connection 
        var dbConnection = new MySqlConnection(GetConnectionString(WowDatabase)); 
        dbConnection.Open(); 
        //Instantiate the Command 
        using (var cmd = new MySqlCommand()) 
        { 
         //Create a new Transaction 
         using (var transaction = dbConnection.BeginTransaction()) 
         { 
          uint lastId = 999999; 
          for (int i = 0; i < dt.Rows.Count; i++) 
          { 
           //var identifier = dt.Rows[i].Field<int>("Identifier"); 
           var id = dt.Rows[i].Field<uint>("Entry"); 
           var name = dt.Rows[i].Field<string>("Name"); 
           var zone = dt.Rows[i].Field<uint>("ZoneID"); 
           var map = dt.Rows[i].Field<uint>("MapID"); 
           var state = dt.Rows[i].Field<Enums.ItemState>("State"); 
           var type = dt.Rows[i].Field<Enums.ObjectType>("Type"); 
           var faction = dt.Rows[i].Field<Enums.FactionType>("Faction"); 
           var x = dt.Rows[i].Field<float>("X"); 
           var y = dt.Rows[i].Field<float>("Y"); 
           var z = dt.Rows[i].Field<float>("Z"); 
           string dataTableName = "entry_" + id; 
           //Create Table if it does not exist. 
           if (id != lastId) 
           { 
            cmd.CommandText = $"CREATE TABLE IF NOT EXISTS `{dataTableName}` (" + 
                 "`identifier` int NOT NULL AUTO_INCREMENT COMMENT 'Auto Incriment Identifier' ," + 
                 "`zone_id`  int NULL COMMENT 'Zone Entry' ," + 
                 "`x_axis`  float NULL COMMENT 'X Axis on Map' ," + 
                 "`y_axis`  float NULL COMMENT 'Y Axis on Map' ," + 
                 "`z_axis`  float NULL COMMENT 'Z Axis on Map' ," + 
                 "`situation` enum('') NULL COMMENT 'Location of the item. Underground, Indoors, Outdoors)' ," + 
                 "`faction`  enum('') NULL COMMENT 'Specifies the Faction which can safely access the item.' ," + 
                 "PRIMARY KEY(`identifier`)" + 
                 ")"; 
            cmd.ExecuteNonQuery(); 
            lastId = id; 
           } 
           //Create command to execute the insertion of Data into desired Table 
           cmd.CommandText = $"INSERT INTO [{dataTableName}] " + 
                 "([identifier], [zone_id], [x_axis], [y_axis], [z_axis], [situation], [faction], [Create_Date], [Update_Date]) " + 
                 "VALUES (@Identifier, @Zone_Id, @X_Axis, @Y_Axis, @Z_Axis, @Situation, @Faction, @Create_Date, @Update_Date)"; 
           //Add data value with Parameters. 
           cmd.CommandType = CommandType.Text; 
           //cmd.Parameters.AddWithValue("@Identifier", identifier); 
           cmd.Parameters.AddWithValue("@Identifier", id); 
           cmd.Parameters.AddWithValue("@Zone_Id", zone); 
           cmd.Parameters.AddWithValue("@X_Axis", x); 
           cmd.Parameters.AddWithValue("@Y_Axis", y); 
           cmd.Parameters.AddWithValue("@Z_Axis", z); 
           cmd.Parameters.AddWithValue("@Situation", state); 
           cmd.Parameters.AddWithValue("@Faction", faction); 
           cmd.Parameters.AddWithValue("@Create_Date", DateTime.Now.Date); 
           cmd.Parameters.AddWithValue("@Update_Date", DateTime.Now.Date); 
    
           cmd.ExecuteNonQuery(); 
          } //for (int i = 0; i < dt.Rows.Count; i++) 
    
          //Commit the Transaction 
          transaction.Commit(); 
         } //using (var transaction = dbConnection.BeginTransaction()) 
        } //using (var cmd = new MySqlCommand()) 
    
        //Close the Connection 
        dbConnection.Close(); 
    

答えて

1

あなたが実際にそれがコマンド、あなたのトランザクションを処理しているのと同じように(の安全に配置されていることを確認するためにusing文の中で、既存のdbConnectionをラップすることができますusing声明

を考えてみましょう等):

//Open the SQL Connection 
using(var dbConnection = new MySqlConnection(GetConnectionString(WowDatabase)) 
{ 
     // Other code omitted for brevity 
} 

一貫した文字列補間

文字列を単に連結する場所は+ですが、ほとんどの場合C#6の文字列補間機能を利用しています。 CommandType.Textがデフォルトであるとして、あなたの実際のcmdオブジェクトのためのあなたのCommandTypeプロパティの設定を削除することができ、

string dataTableName = $"entry_{id}"; 

さらにCommandType

を設定するための必要はありませんが:あなたはどこにでもそれを使用していない検討する必要があります:

//cmd.CommandType = CommandType.Text; 
+0

ありがとう、私は変更を加えました。したがって、構文を別にすれば、私のTransactionの使用は正しいのでしょうか?それは繰り返しでsqlコマンドを実行し、forループが完了したらそれらをコミットしますか? –

+0

Johnが提起した問題は問題ではないことを前提としています( 'CREATE TABLE'呼び出しによってコミットがトリガーされている)、うまく見えます。 –

2

これは(期待通りに)MySqlではうまくいかないと思います。暗黙のコミットを引き起こすいくつかのステートメントがあります - CREATE TABLEがその1つです。

http://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html

+0

興味深い。私はこれをSQL CEからリファクタリングしていましたが、それはそのままではないと思います。これを私の注目に持ってくれてありがとう!私はこれを回避するために "Select table_name from information_schema.tables"を使用しています。これはMySQLで動作しますか? –

+0

私はそれが動作しない理由が表示されません。 'transaction.Commit()'を実行する前にテーブルが作成されることだけを知っておいてください。 –

+0

あなたの答えが最初は間違っていました。これを指摘してくれてありがとう! –