回答編集履歴

3

追記2

2017/11/19 15:21

投稿

umyu
umyu

スコア5846

test CHANGED
@@ -64,8 +64,6 @@
64
64
 
65
65
 
66
66
 
67
-
68
-
69
67
  2,まず開発の要件定義/要求仕様とCustomersController側がどういうSQLアクセスが必要かによるのですが、疑似コードを書きます。
70
68
 
71
69
 
@@ -80,84 +78,86 @@
80
78
 
81
79
 
82
80
 
83
- private readonly string ConnectionString;
81
+ private readonly string ConnectionString;
84
-
82
+
85
- private readonly string id;
83
+ private readonly string id;
86
-
84
+
87
- private readonly int ConnectionTimeout;
85
+ private readonly int ConnectionTimeout;
88
-
89
-
90
-
86
+
87
+
88
+
91
- public DBHelper(string id) {
89
+ public DBHelper(string id) {
92
-
90
+
93
- this.id = id;
91
+ this.id = id;
94
-
92
+
95
- //SqlConnectionStringBuilderを使ったConnectionString作成処理
93
+ //SqlConnectionStringBuilderを使ったConnectionString作成処理
96
-
94
+
97
- this.ConnectionString = dbConString.ConnectionString;
95
+ this.ConnectionString = dbConString.ConnectionString;
98
-
96
+
99
- //設定ファイル等からtimeout値を格納
97
+ //設定ファイル等からtimeout値を格納
100
-
98
+
101
- this.ConnectionTimeout = 1000;
99
+ this.ConnectionTimeout = 1000;
100
+
101
+ }
102
+
103
+ public SqlConnection getSqlConnection() {
104
+
105
+ SqlConnection con = new SqlConnection(this.ConnectionString);
106
+
107
+ con.ConnectionTimeout = this.ConnectionTimeout;
108
+
109
+ return con;
110
+
111
+ }
102
112
 
103
113
  }
104
114
 
115
+ ```
116
+
117
+ ◆CustomersController#PutCustomer側
118
+
119
+ ```C#
120
+
121
+ DBHelper db = new DBHelper("exsample");
122
+
105
- public SqlConnection getSqlConnection();
123
+ using(SqlConnection con = db.getSqlConnection()) {
124
+
106
-
125
+ //やりたいこと。
126
+
127
+ };
128
+
129
+ ```
130
+
131
+ これでConnectionString作成処理とConnectionTimeoutの設定処理はDBHelper側で管理して、**CustomersController#PutCustomer側は関知しない**という形に変更できます。
132
+
133
+ 関知しないというのがポイントです、PutCustomer側が主として行いたい事はデーターベースの更新処理です。ConnectionString、ConnectionTimeoutの設定ではありません。
134
+
135
+ getSqlCommandやgetSqlTransactionを追加することで、実行するSQLをファイルに書き出したりもできるようになります。
136
+
137
+ DBHelperに渡すID値の管理はSQLトランザクションの要件(コネクションタイムアウト値、トランザクションタイムアウト値、トランザクション分離レベル(isolation level))によって異なるので、それに合わせた形がいいと思います。
138
+
139
+ windows formならリフレクションで実行のメソッド名が取れた記憶がありますが。
140
+
141
+ 難易度が上がりますが、[TransactionScopeクラス](https://msdn.microsoft.com/ja-jp/library/system.transactions.transactionscope(v=vs.110).aspx)、拡張メソッドを使った書き方やイベントを使った書き方もあるので、時間がある時に試行錯誤してみてくださいな。
142
+
143
+
144
+
145
+ 3,[using SqlConnection](https://msdn.microsoft.com/ja-jp/library/system.data.sqlclient.sqlconnection(v=vs.110).aspx)で検索してみてください。
146
+
147
+
148
+
149
+ ```C#
150
+
107
- SqlConnection con = new SqlConnection(this.ConnectionString);
151
+ using (SqlConnection con = new SqlConnection(dbConString.ConnectionString)){
108
-
109
- con.ConnectionTimeout = this.ConnectionTimeout;
152
+
110
-
111
- return con;
153
+ // 行いたい処理
154
+
155
+
112
156
 
113
157
  }
114
158
 
115
159
  ```
116
160
 
117
-
118
-
119
- ◆CustomersController#PutCustomer側
120
-
121
- ```C#
122
-
123
- DBHelper db = new DBHelper("exsample");
124
-
125
- using(SqlConnection con = db.getSqlConnection()) {
126
-
127
- //やりたいこと。
128
-
129
- };
130
-
131
- ```
132
-
133
- これでConnectionString作成処理とConnectionTimeoutの設定処理はDBHelper側で管理して、CustomersController#PutCustomer側は関知しないという形にできます。
134
-
135
- getSqlCommandやgetSqlTransactionを追加することで、実行するSQLをファイルに書き出したりもできるようになります。
136
-
137
- DBHelperに渡すID値の管理はSQLトランザクションの要件(コネクションタイムアウト値、トランザクションタイムアウト値、トランザクション分離レベル(isolation level))によって異なるので、それに合わせた形がいいと思います。
138
-
139
- windows formならリフレクションで実行のメソッド名が取れた記憶がありますが。
140
-
141
- 難易度が上がりますが、拡張メソッドを使った書き方やイベントを使った書き方もあるので、時間がある時に試行錯誤してみてくださいな。
142
-
143
-
144
-
145
- 3,using SqlConnectionで検索してみてください。
146
-
147
- https://msdn.microsoft.com/ja-jp/library/system.data.sqlclient.sqlconnection(v=vs.110).aspx
148
-
149
- ```C#
150
-
151
- using (SqlConnection con = new SqlConnection(dbConString.ConnectionString)){
152
-
153
- // 行いたい処理
154
-
155
-
156
-
157
- }
158
-
159
- ```
160
-
161
161
  SqlTransactionはusingで囲むとデフォルト処理がrollbackなので注意です。
162
162
 
163
163
  コミット処理 sqlTran.Commit();を入れてください。

2

コメント欄の質問に追加回答

2017/11/19 15:21

投稿

umyu
umyu

スコア5846

test CHANGED
@@ -51,3 +51,157 @@
51
51
 
52
52
 
53
53
  8,SQLに値を設定する時は[SqlParameter](https://msdn.microsoft.com/ja-jp/library/system.data.sqlclient.sqlparameter(v=vs.110).aspx)クラスを最低でも使用してください。
54
+
55
+
56
+
57
+ ---
58
+
59
+ 2017/11/19追記
60
+
61
+ 1,更新要件によるのですが、例えば標準単価マスタ(例)の値を参照(SELECT)して、明細(トランザクションデータ)にUPDATEする時です。
62
+
63
+ WEBAPIとのことなので、SQLトランザクションの時間がそこまで長くなるとはあまり思えませんが、念のための情報です。
64
+
65
+
66
+
67
+
68
+
69
+ 2,まず開発の要件定義/要求仕様とCustomersController側がどういうSQLアクセスが必要かによるのですが、疑似コードを書きます。
70
+
71
+
72
+
73
+ ◆SqlConnectionを生成しオプション値を設定するためだけのクラス。
74
+
75
+ ```C#
76
+
77
+ using System.Collections.Generic;
78
+
79
+ class DBHelper {
80
+
81
+
82
+
83
+ private readonly string ConnectionString;
84
+
85
+ private readonly string id;
86
+
87
+ private readonly int ConnectionTimeout;
88
+
89
+
90
+
91
+ public DBHelper(string id) {
92
+
93
+ this.id = id;
94
+
95
+ //SqlConnectionStringBuilderを使ったConnectionString作成処理
96
+
97
+ this.ConnectionString = dbConString.ConnectionString;
98
+
99
+ //設定ファイル等からtimeout値を格納
100
+
101
+ this.ConnectionTimeout = 1000;
102
+
103
+ }
104
+
105
+ public SqlConnection getSqlConnection();
106
+
107
+ SqlConnection con = new SqlConnection(this.ConnectionString);
108
+
109
+ con.ConnectionTimeout = this.ConnectionTimeout;
110
+
111
+ return con;
112
+
113
+ }
114
+
115
+ ```
116
+
117
+
118
+
119
+ ◆CustomersController#PutCustomer側
120
+
121
+ ```C#
122
+
123
+ DBHelper db = new DBHelper("exsample");
124
+
125
+ using(SqlConnection con = db.getSqlConnection()) {
126
+
127
+ //やりたいこと。
128
+
129
+ };
130
+
131
+ ```
132
+
133
+ これでConnectionString作成処理とConnectionTimeoutの設定処理はDBHelper側で管理して、CustomersController#PutCustomer側は関知しないという形にできます。
134
+
135
+ getSqlCommandやgetSqlTransactionを追加することで、実行するSQLをファイルに書き出したりもできるようになります。
136
+
137
+ DBHelperに渡すID値の管理はSQLトランザクションの要件(コネクションタイムアウト値、トランザクションタイムアウト値、トランザクション分離レベル(isolation level))によって異なるので、それに合わせた形がいいと思います。
138
+
139
+ windows formならリフレクションで実行のメソッド名が取れた記憶がありますが。
140
+
141
+ 難易度が上がりますが、拡張メソッドを使った書き方やイベントを使った書き方もあるので、時間がある時に試行錯誤してみてくださいな。
142
+
143
+
144
+
145
+ 3,using SqlConnectionで検索してみてください。
146
+
147
+ https://msdn.microsoft.com/ja-jp/library/system.data.sqlclient.sqlconnection(v=vs.110).aspx
148
+
149
+ ```C#
150
+
151
+ using (SqlConnection con = new SqlConnection(dbConString.ConnectionString)){
152
+
153
+ // 行いたい処理
154
+
155
+
156
+
157
+ }
158
+
159
+ ```
160
+
161
+ SqlTransactionはusingで囲むとデフォルト処理がrollbackなので注意です。
162
+
163
+ コミット処理 sqlTran.Commit();を入れてください。
164
+
165
+
166
+
167
+ 7,まず「ストアドプロシージャ 利点 欠点」で検索してみてください。
168
+
169
+ 番号を発行する処理はSQLサーバーのsequence(シーケンスオブジェクト)に任せた方がいいのですが。
170
+
171
+ 質問文のソースコードの書き方を見る限りでは使ってなさそうに見えたので。
172
+
173
+
174
+
175
+ ◆取引番号を付番する処理を考えた時、
176
+
177
+ 1,番号を発行し、その値を使用する。
178
+
179
+ 1-1,番号発行.
180
+
181
+ 1-2,発行された番号をプログラムで使用。
182
+
183
+
184
+
185
+ 2,発行されている番号を使用し、次の番号を発行する。
186
+
187
+ 2-1,発行されている番号をプログラムで使用。
188
+
189
+ 2-2,次の番号を予約発行.
190
+
191
+
192
+
193
+ この2パターンがあります、設計者、開発者間で確実に周知されている必要があり、開発規模によっては容易に伝達ミスが発生します。
194
+
195
+ 一般的に発行した番号は会社外部に出ることが多く番号が間違ってた時や管理が大変です。
196
+
197
+ この点をストアドプロシージャを使うことでDB側で付番を管理し統一した形で処理が管理を行えます。
198
+
199
+
200
+
201
+ 8 ,質問文の sql = "UPDATE USER_MASTER SET DEPT_NO = '0004' WHERE USER_ID = '0001' ";
202
+
203
+ UPDATE文でDEPT_NOとUSER_ID の値の割当を行ってますが、この部分の話です。
204
+
205
+ 追加プロジェクトはPutCustomerの引数から割り当てる方なりますが、文字列連結 + でSQLを組み立てるとSQLインジェクションが発生します。
206
+
207
+ SQLインジェクションを防止するために「SqlParameter 使い方」で検索してみてください。

1

追記

2017/11/19 15:00

投稿

umyu
umyu

スコア5846

test CHANGED
@@ -47,3 +47,7 @@
47
47
 
48
48
 
49
49
  7,番号を発行する処理に関してはDBのストアドプロシージャにして、それをAP側で呼び出す形にしたほうがあと後の事を考えるといいと思います。
50
+
51
+
52
+
53
+ 8,SQLに値を設定する時は[SqlParameter](https://msdn.microsoft.com/ja-jp/library/system.data.sqlclient.sqlparameter(v=vs.110).aspx)クラスを最低でも使用してください。