1 using System; 2 using System.Collections.Generic; 3 using System.Data; 4 using System.Data.SqlClient; 5 using System.Reflection; 6 7 namespace DAL.DataUtil 8 { 9 /// <summary> 10 /// SqlServer数据访问控制类 11 /// </summary> 12 public class DataProvider 13 { 14 public string ConnectionString { get; set; } 15 16 #region 私有方法 17 18 /// <summary> 19 /// SqlCommand 对象执行SQL脚本前的准备工作 20 /// </summary> 21 /// <param name="cmd">SqlCommand 对象</param> 22 /// <param name="conn">SqlConnection 对象</param> 23 /// <param name="trans">SqlTransaction 对象</param> 24 /// <param name="cmdType">命令类型:存储过程或普通SQL脚本</param> 25 /// <param name="cmdText">SQL脚本</param> 26 /// <param name="cmdParms">SqlCommand 对象使用的 SqlParameter 参数集合</param> 27 private void PrepareCommand(SqlCommand cmd, SqlConnection conn, SqlTransaction trans, 28 CommandType cmdType, string cmdText, SqlParameter[] cmdParms) 29 { 30 if (conn.State != ConnectionState.Open) 31 conn.Open(); 32 33 cmd.Connection = conn; 34 cmd.CommandText = cmdText; 35 cmd.CommandType = cmdType; 36 37 if (trans != null) 38 cmd.Transaction = trans; 39 40 if (cmdParms != null) 41 { 42 foreach (SqlParameter param in cmdParms) 43 cmd.Parameters.Add(param); 44 } 45 } 46 47 /// <summary> 48 /// SqlDataAdapter 对象使用前的准备工作 49 /// </summary> 50 /// <param name="adapter">SqlDataAdapter 对象</param> 51 /// <param name="conn">SqlConnection 对象</param> 52 /// <param name="cmdType">命令类型:存储过程或普通SQL脚本</param> 53 /// <param name="cmdText">SQL脚本</param> 54 /// <param name="cmdParms">SqlCommand 对象使用的 SqlParameter 参数集合</param> 55 private void PrepareAdapter(SqlDataAdapter adapter, SqlConnection conn, 56 CommandType cmdType, string cmdText, SqlParameter[] cmdParms) 57 { 58 SqlCommand cmd = new SqlCommand(cmdText, conn); 59 60 cmd.CommandType = cmdType; 61 if (cmdParms != null) 62 { 63 foreach (SqlParameter param in cmdParms) 64 cmd.Parameters.Add(param); 65 } 66 adapter.SelectCommand = cmd; 67 } 68 69 #endregion 70 71 #region 公有方法 72 73 /// <summary> 74 /// 对连接执行 SQL 语句并返回受影响的行数。 75 /// </summary> 76 /// <param name="cmdText">SQL脚本</param> 77 /// <param name="cmdType">命令类型:存储过程或普通SQL脚本</param> 78 /// <returns>受影响的行数</returns> 79 public int ExecuteNonQuery(string cmdText, CommandType cmdType) 80 { 81 return ExecuteNonQuery(cmdText, cmdType, null); 82 } 83 84 /// <summary> 85 /// 对连接执行 SQL 语句并返回受影响的行数。 86 /// </summary> 87 /// <param name="cmdText">SQL脚本</param> 88 /// <param name="cmdType">命令类型:存储过程或普通SQL脚本</param> 89 /// <param name="parameters">SqlParameter 参数集合</param> 90 /// <returns>受影响的行数</returns> 91 public int ExecuteNonQuery(string cmdText, CommandType cmdType, SqlParameter[] parameters) 92 { 93 SqlCommand cmd = new SqlCommand(); 94 int val = 0; 95 using (SqlConnection conn = new SqlConnection(ConnectionString)) 96 { 97 conn.Open(); 98 try 99 { 100 PrepareCommand(cmd, conn, null, cmdType, cmdText, parameters); 101 val = cmd.ExecuteNonQuery(); 102 if (parameters != null) 103 { 104 cmd.Parameters.Clear(); 105 } 106 } 107 catch 108 { 109 conn.Close(); 110 conn.Dispose(); 111 } 112 finally 113 { 114 if (conn.State != ConnectionState.Closed) 115 { 116 conn.Close(); 117 conn.Dispose(); 118 } 119 } 120 return val; 121 } 122 } 123 124 /// <summary> 125 /// 对连接执行多条 SQL 语句,并加入事务处理 126 /// </summary> 127 /// <param name="cmdTexts">SQL 语句数组</param> 128 public void ExecuteNonQueryWithTransaction(string[] cmdTexts) 129 { 130 SqlCommand cmd = new SqlCommand(); 131 132 using (SqlConnection conn = new SqlConnection(ConnectionString)) 133 { 134 conn.Open(); 135 SqlTransaction trans = conn.BeginTransaction(); 136 137 try 138 { 139 foreach (string sql in cmdTexts) 140 { 141 PrepareCommand(cmd, conn, trans, CommandType.Text, sql, null); 142 cmd.ExecuteNonQuery(); 143 } 144 trans.Commit(); 145 } 146 catch 147 { 148 trans.Rollback(); 149 conn.Close(); 150 conn.Dispose(); 151 } 152 finally 153 { 154 if (conn.State != ConnectionState.Closed) 155 { 156 conn.Close(); 157 conn.Dispose(); 158 } 159 } 160 } 161 } 162 163 /// <summary> 164 /// 对连接执行多条 SQL 语句,并加入事务处理 165 /// </summary> 166 /// <param name="commands">SQL命令数组。 167 /// Command 封装了 SqlCommand 对象需要的 CommandText、CommandType、SqlParameterCollection,以便分别执行每一组SQL脚本</param> 168 public void ExecuteNonQueryWithTransaction(Command[] commands) 169 { 170 SqlCommand cmd = new SqlCommand(); 171 172 using (SqlConnection conn = new SqlConnection(ConnectionString)) 173 { 174 conn.Open(); 175 SqlTransaction trans = conn.BeginTransaction(); 176 177 try 178 { 179 foreach (Command command in commands) 180 { 181 PrepareCommand(cmd, conn, trans, command.CommandType, command.CommandText, command.Parameters); 182 cmd.ExecuteNonQuery(); 183 if (command.Parameters != null) 184 { 185 cmd.Parameters.Clear(); 186 } 187 } 188 trans.Commit(); 189 } 190 catch 191 { 192 trans.Rollback(); 193 conn.Close(); 194 conn.Dispose(); 195 } 196 finally 197 { 198 if (conn.State != ConnectionState.Closed) 199 { 200 conn.Close(); 201 conn.Dispose(); 202 } 203 } 204 } 205 } 206 207 /// <summary> 208 /// 执行SQL脚本,返回查询得到的 DataReader 结果集 209 /// </summary> 210 /// <param name="cmdText">SQL脚本</param> 211 /// <param name="cmdType">命令类型:存储过程或普通SQL脚本</param> 212 /// <returns>DataReader 结果集</returns> 213 public SqlDataReader ExecuteReader(string cmdText, CommandType cmdType) 214 { 215 return ExecuteReader(cmdText, cmdType, null); 216 } 217 218 /// <summary> 219 /// 执行SQL脚本进行查询,返回得到的 DataReader 结果集 220 /// </summary> 221 /// <param name="cmdText">SQL脚本</param> 222 /// <param name="cmdType">命令类型:存储过程或普通SQL脚本</param> 223 /// <param name="parameters">SqlParameter 参数集合</param> 224 /// <returns>DataReader 结果集</returns> 225 public SqlDataReader ExecuteReader(string cmdText, CommandType cmdType, SqlParameter[] parameters) 226 { 227 SqlCommand cmd = new SqlCommand(); 228 SqlConnection conn = new SqlConnection(ConnectionString); 229 230 try 231 { 232 PrepareCommand(cmd, conn, null, cmdType, cmdText, parameters); 233 SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection); 234 if (parameters != null) 235 { 236 cmd.Parameters.Clear(); 237 } 238 239 return reader; 240 } 241 catch 242 { 243 conn.Close(); 244 conn.Dispose(); 245 throw; 246 } 247 finally 248 { 249 if (conn.State != ConnectionState.Closed) 250 { 251 conn.Close(); 252 conn.Dispose(); 253 } 254 } 255 } 256 257 /// <summary> 258 /// 执行查询,并返回查询所返回的结果集中第一行的第一列。忽略其他列或行。 259 /// </summary> 260 /// <param name="cmdText">SQL脚本</param> 261 /// <param name="cmdType">命令类型:存储过程或普通SQL脚本</param> 262 /// <returns>结果集中第一行的第一列</returns> 263 public object ExecuteScalar(string cmdText, CommandType cmdType) 264 { 265 return ExecuteScalar(cmdText, cmdType, null); 266 } 267 268 /// <summary> 269 /// 执行查询,并返回查询所返回的结果集中第一行的第一列。忽略其他列或行。 270 /// </summary> 271 /// <param name="cmdText">SQL脚本</param> 272 /// <param name="cmdType">命令类型:存储过程或普通SQL脚本</param> 273 /// <param name="parameters">SqlParameter 参数集合</param> 274 /// <returns>结果集中第一行的第一列</returns> 275 public object ExecuteScalar(string cmdText, CommandType cmdType, SqlParameter[] parameters) 276 { 277 SqlCommand cmd = new SqlCommand(); 278 object val = new object(); 279 using (SqlConnection conn = new SqlConnection(ConnectionString)) 280 { 281 conn.Open(); 282 try 283 { 284 PrepareCommand(cmd, conn, null, cmdType, cmdText, parameters); 285 val = cmd.ExecuteScalar(); 286 if (parameters != null) 287 { 288 cmd.Parameters.Clear(); 289 } 290 } 291 catch 292 { 293 conn.Close(); 294 conn.Dispose(); 295 } 296 finally 297 { 298 if (conn.State != ConnectionState.Closed) 299 { 300 conn.Close(); 301 conn.Dispose(); 302 } 303 } 304 return val; 305 } 306 } 307 308 /// <summary> 309 /// 执行查询,将查询结果填充到 DataSet 并返回 310 /// </summary> 311 /// <param name="cmdText">SQL脚本</param> 312 /// <param name="cmdType">命令类型:存储过程或普通SQL脚本</param> 313 /// <returns>查询结果集</returns> 314 public DataSet FillDataSet(string cmdText, CommandType cmdType) 315 { 316 return FillDataSet(cmdText, cmdType, null); 317 } 318 319 /// <summary> 320 /// 执行查询,将查询结果填充到 DataSet 并返回 321 /// </summary> 322 /// <param name="cmdText">SQL脚本</param> 323 /// <param name="cmdType">命令类型:存储过程或普通SQL脚本</param> 324 /// <param name="parameters">SqlParameter 参数集合</param> 325 /// <returns>查询结果集</returns> 326 public DataSet FillDataSet(string cmdText, CommandType cmdType, SqlParameter[] parameters) 327 { 328 SqlDataAdapter adapter = new SqlDataAdapter(); 329 DataSet dataSet = new DataSet(); 330 using (SqlConnection conn = new SqlConnection(ConnectionString)) 331 { 332 conn.Open(); 333 try 334 { 335 PrepareAdapter(adapter, conn, cmdType, cmdText, parameters); 336 adapter.Fill(dataSet); 337 } 338 catch 339 { 340 conn.Close(); 341 conn.Dispose(); 342 } 343 finally 344 { 345 if (conn.State != ConnectionState.Closed) 346 { 347 conn.Close(); 348 conn.Dispose(); 349 } 350 } 351 return dataSet; 352 } 353 } 354 355 /// <summary> 356 /// 执行查询,将查询结果填充到 DataTable 并返回 357 /// </summary> 358 /// <param name="cmdText">SQL脚本</param> 359 /// <param name="cmdType">命令类型:存储过程或普通SQL脚本</param> 360 /// <returns>查询结果集</returns> 361 public DataTable FillDataTable(string cmdText, CommandType cmdType) 362 { 363 return FillDataTable(cmdText, cmdType, null); 364 } 365 366 /// <summary> 367 /// 执行查询,将查询结果填充到 DataTable 并返回 368 /// </summary> 369 /// <param name="cmdText">SQL脚本</param> 370 /// <param name="cmdType">命令类型:存储过程或普通SQL脚本</param> 371 /// <param name="parameters">SqlParameter 参数集合</param> 372 /// <returns>查询结果集</returns> 373 public DataTable FillDataTable(string cmdText, CommandType cmdType, SqlParameter[] parameters) 374 { 375 SqlDataAdapter adapter = new SqlDataAdapter(); 376 DataTable table = new DataTable(); 377 using (SqlConnection conn = new SqlConnection(ConnectionString)) 378 { 379 conn.Open(); 380 try 381 { 382 PrepareAdapter(adapter, conn, cmdType, cmdText, parameters); 383 adapter.Fill(table); 384 } 385 catch 386 { 387 conn.Close(); 388 conn.Dispose(); 389 } 390 finally 391 { 392 if (conn.State != ConnectionState.Closed) 393 { 394 conn.Close(); 395 conn.Dispose(); 396 } 397 } 398 return table; 399 } 400 } 401 402 /// <summary> 403 /// 执行只返回一条记录的查询,把返回的记录反射成一个实体对象,实体对象类型由传入的类型决定。 404 /// 传入的类型和返回类型要一致 405 /// </summary> 406 /// <typeparam name="T">要反射封装的对象实体类型。必须和返回类型一致</typeparam> 407 /// <param name="cmdText">SQL脚本</param> 408 /// <param name="cmdType">命令类型:存储过程或普通SQL脚本</param> 409 /// <returns>封装好的对象实体。必须和传入参数类型一致</returns> 410 public T ReflectObject<T>(string cmdText, CommandType cmdType) 411 { 412 return ReflectObject<T>(cmdText, cmdType, null); 413 } 414 415 /// <summary> 416 /// 执行只返回一条记录的查询,把返回的记录反射成一个实体对象,实体对象类型由传入的类型决定。 417 /// 传入的类型和返回类型要一致 418 /// </summary> 419 /// <typeparam name="T">要反射封装的对象实体类型。必须和返回类型一致</typeparam> 420 /// <param name="cmdText">SQL脚本</param> 421 /// <param name="cmdType">命令类型:存储过程或普通SQL脚本</param> 422 /// <param name="parameters">SqlParameter 参数集合</param> 423 /// <returns>封装好的对象实体。必须和传入参数类型一致</returns> 424 public T ReflectObject<T>(string cmdText, CommandType cmdType, SqlParameter[] parameters) 425 { 426 SqlCommand cmd = new SqlCommand(); 427 T obj = default(T); 428 429 using (SqlConnection conn = new SqlConnection(ConnectionString)) 430 { 431 PrepareCommand(cmd, conn, null, cmdType, cmdText, parameters); 432 433 using (SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection | CommandBehavior.SingleRow)) 434 { 435 if (reader.Read()) 436 { 437 obj = (T)Activator.CreateInstance(typeof(T)); 438 Type type = obj.GetType(); 439 440 for (int i = 0; i < reader.FieldCount; i++) 441 { 442 if (!reader.IsDBNull(i)) 443 { 444 try 445 { 446 type.InvokeMember(reader.GetName(i), BindingFlags.Default | BindingFlags.SetProperty, null, obj, new object[] { reader.GetValue(i) }); 447 } 448 catch (MissingMemberException exception) 449 { 450 //Column/Property names don't match, thus throwing an exception. Ignored 451 System.Diagnostics.Debug.WriteLine(exception.Message); 452 } 453 } 454 } 455 456 reader.Close(); 457 } 458 } 459 if (conn.State != ConnectionState.Closed) 460 { 461 conn.Close(); 462 } 463 } 464 465 return obj; 466 } 467 468 /// <summary> 469 /// 执行查询,把返回的记录集反射成一个实体对象集合,实体对象类型由传入的类型决定。 470 /// 传入的类型和返回类型要一致 471 /// </summary> 472 /// <typeparam name="T">要反射封装的对象实体类型。必须和返回类型一致</typeparam> 473 /// <param name="cmdText">SQL脚本</param> 474 /// <param name="cmdType">命令类型:存储过程或普通SQL脚本</param> 475 /// <returns>封装好的实体集合。必须和传入参数类型一致</returns> 476 public List<T> ReflectCollection<T>(string cmdText, CommandType cmdType) 477 { 478 return ReflectCollection<T>(cmdText, cmdType, null); 479 } 480 481 /// <summary> 482 /// 执行查询,把返回的记录集反射成一个实体对象集合,实体对象类型由传入的类型决定。 483 /// 传入的类型和返回类型要一致 484 /// </summary> 485 /// <typeparam name="T">要反射封装的对象实体类型。必须和返回类型一致</typeparam> 486 /// <param name="cmdText">SQL脚本</param> 487 /// <param name="cmdType">命令类型:存储过程或普通SQL脚本</param> 488 /// <param name="parameters">SqlParameter 参数集合</param> 489 /// <returns>封装好的实体集合。必须和传入参数类型一致</returns> 490 public List<T> ReflectCollection<T>(string cmdText, CommandType cmdType, SqlParameter[] parameters) 491 { 492 SqlCommand cmd = new SqlCommand(); 493 494 using (SqlConnection conn = new SqlConnection(ConnectionString)) 495 { 496 PrepareCommand(cmd, conn, null, cmdType, cmdText, parameters); 497 498 using (SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection)) 499 { 500 List<T> objList = new List<T>(); 501 502 while (reader.Read()) 503 { 504 T obj = (T)Activator.CreateInstance(typeof(T)); 505 Type type = obj.GetType(); 506 507 for (int i = 0; i < reader.FieldCount; i++) 508 { 509 if (!reader.IsDBNull(i)) 510 { 511 try 512 { 513 type.InvokeMember(reader.GetName(i), BindingFlags.Default | BindingFlags.SetProperty, null, obj, new object[] { reader.GetValue(i) }); 514 } 515 catch (MissingMemberException exception) 516 { 517 //Column/Property names don't match, thus throwing an exception. Ignored 518 System.Diagnostics.Debug.WriteLine(exception.Message); 519 } 520 } 521 } 522 objList.Add(obj); 523 } 524 525 reader.Close(); 526 if (conn.State != ConnectionState.Closed) 527 { 528 conn.Close(); 529 } 530 return objList; 531 } 532 } 533 } 534 535 #endregion 536 } 537 }