Mercurial > pub > bltoolkit
comparison Source/Data/DbManager.cs @ 0:f990fcb411a9
Копия текущей версии из github
author | cin |
---|---|
date | Thu, 27 Mar 2014 21:46:09 +0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:f990fcb411a9 |
---|---|
1 using System; | |
2 using System.Collections; | |
3 using System.Collections.Generic; | |
4 using System.ComponentModel; | |
5 using System.Data; | |
6 using System.Data.Common; | |
7 using System.Data.SqlTypes; | |
8 using System.Diagnostics; | |
9 using System.Text; | |
10 | |
11 #region ReSharper disable | |
12 // ReSharper disable UnusedParameter.Local | |
13 #pragma warning disable 1589 | |
14 #endregion | |
15 | |
16 namespace BLToolkit.Data | |
17 { | |
18 using Common; | |
19 using DataProvider; | |
20 using Mapping; | |
21 using Properties; | |
22 using Reflection; | |
23 using Sql; | |
24 | |
25 /// <summary> | |
26 /// The <b>DbManager</b> is a primary class of the <see cref="BLToolkit.Data"/> namespace | |
27 /// that can be used to execute commands of different database providers. | |
28 /// </summary> | |
29 /// <remarks> | |
30 /// When the <b>DbManager</b> goes out of scope, it does not close the internal connection object. | |
31 /// Therefore, you must explicitly close the connection by calling <see cref="Close"/> or | |
32 /// <see cref="Dispose(bool)"/>. Also, you can use the C# <b>using</b> statement. | |
33 /// </remarks> | |
34 /// <include file="Examples.xml" path='examples/db[@name="DbManager"]/*' /> | |
35 [DesignerCategory(@"Code")] | |
36 public partial class DbManager: Component | |
37 { | |
38 #region Init | |
39 | |
40 public DbManager(DataProviderBase dataProvider, string connectionString) | |
41 { | |
42 if (dataProvider == null) throw new ArgumentNullException("dataProvider"); | |
43 if (connectionString == null) throw new ArgumentNullException("connectionString"); | |
44 | |
45 _dataProvider = dataProvider; | |
46 _connection = dataProvider.CreateConnectionObject(); | |
47 | |
48 _connection.ConnectionString = connectionString; | |
49 | |
50 _dataProvider.InitDbManager(this); | |
51 } | |
52 | |
53 public DbManager(DataProviderBase dataProvider, IDbConnection connection) | |
54 { | |
55 if (dataProvider == null) throw new ArgumentNullException("dataProvider"); | |
56 if (connection == null) throw new ArgumentNullException("connection"); | |
57 | |
58 _dataProvider = dataProvider; | |
59 _connection = connection; | |
60 | |
61 _dataProvider.InitDbManager(this); | |
62 } | |
63 | |
64 public DbManager(DataProviderBase dataProvider, IDbTransaction transaction) | |
65 { | |
66 if (dataProvider == null) throw new ArgumentNullException("dataProvider"); | |
67 if (transaction == null) throw new ArgumentNullException("transaction"); | |
68 | |
69 _dataProvider = dataProvider; | |
70 _connection = transaction.Connection; | |
71 _transaction = transaction; | |
72 _closeTransaction = false; | |
73 | |
74 _dataProvider.InitDbManager(this); | |
75 } | |
76 | |
77 DbManager(int n) | |
78 { | |
79 } | |
80 | |
81 public virtual DbManager Clone() | |
82 { | |
83 var clone = | |
84 new DbManager(0) | |
85 { | |
86 _configurationString = _configurationString, | |
87 _dataProvider = _dataProvider, | |
88 _mappingSchema = _mappingSchema | |
89 }; | |
90 | |
91 if (_connection != null) | |
92 clone._connection = CloneConnection(); | |
93 | |
94 return clone; | |
95 } | |
96 | |
97 public string LastQuery; | |
98 | |
99 #endregion | |
100 | |
101 #region Public Properties | |
102 | |
103 private MappingSchema _mappingSchema = Map.DefaultSchema; | |
104 /// <summary> | |
105 /// Gets the <see cref="BLToolkit.Mapping.MappingSchema"/> | |
106 /// used by this instance of the <see cref="DbManager"/>. | |
107 /// </summary> | |
108 /// <value> | |
109 /// A mapping schema. | |
110 /// </value> | |
111 public MappingSchema MappingSchema | |
112 { | |
113 [DebuggerStepThrough] | |
114 get { return _mappingSchema; } | |
115 set { _mappingSchema = value ?? Map.DefaultSchema; } | |
116 } | |
117 | |
118 private DataProviderBase _dataProvider; | |
119 /// <summary> | |
120 /// Gets the <see cref="BLToolkit.Data.DataProvider.DataProviderBase"/> | |
121 /// used by this instance of the <see cref="DbManager"/>. | |
122 /// </summary> | |
123 /// <value> | |
124 /// A data provider. | |
125 /// </value> | |
126 /// <include file="Examples.xml" path='examples/db[@name="DataProvider"]/*' /> | |
127 public DataProviderBase DataProvider | |
128 { | |
129 [DebuggerStepThrough] | |
130 get { return _dataProvider; } | |
131 protected set { _dataProvider = value; } | |
132 } | |
133 | |
134 private static TraceSwitch _traceSwitch; | |
135 public static TraceSwitch TraceSwitch | |
136 { | |
137 get { return _traceSwitch ?? (_traceSwitch = new TraceSwitch("DbManager", "DbManager trace switch", | |
138 #if DEBUG | |
139 "Warning" | |
140 #else | |
141 "Off" | |
142 #endif | |
143 )); } | |
144 set { _traceSwitch = value; } | |
145 } | |
146 | |
147 public static void TurnTraceSwitchOn() | |
148 { | |
149 TraceSwitch = new TraceSwitch("DbManager", "DbManager trace switch", "Info"); | |
150 } | |
151 | |
152 public static Action<string,string> WriteTraceLine = (message, displayName) => Debug.WriteLine(message, displayName); | |
153 | |
154 private bool _canRaiseEvents = true; | |
155 public new bool CanRaiseEvents | |
156 { | |
157 get { return _canRaiseEvents && base.CanRaiseEvents; } | |
158 set { _canRaiseEvents = value; } | |
159 } | |
160 | |
161 /// <summary> | |
162 /// Use plain text query instead of using command parameters | |
163 /// </summary> | |
164 public bool UseQueryText { get; set; } | |
165 | |
166 #endregion | |
167 | |
168 #region Connection | |
169 | |
170 private bool _closeConnection; | |
171 private IDbConnection _connection; | |
172 /// <summary> | |
173 /// Gets or sets the <see cref="IDbConnection"/> used by this instance of the <see cref="DbManager"/>. | |
174 /// </summary> | |
175 /// <value> | |
176 /// The connection to the data source. | |
177 /// </value> | |
178 /// <remarks> | |
179 /// Then you set a connection object, it has to match the data source type. | |
180 /// </remarks> | |
181 /// <exception cref="DataException"> | |
182 /// A connection does not match the data source type. | |
183 /// </exception> | |
184 /// <include file="Examples.xml" path='examples/db[@name="Connection"]/*' /> | |
185 public IDbConnection Connection | |
186 { | |
187 [DebuggerStepThrough] | |
188 get | |
189 { | |
190 if (_connection.State == ConnectionState.Closed) | |
191 OpenConnection(); | |
192 return _connection; | |
193 } | |
194 | |
195 set | |
196 { | |
197 if (value == null) | |
198 throw new ArgumentNullException("value"); | |
199 | |
200 if (value.GetType() != _dataProvider.ConnectionType) | |
201 InitDataProvider(value); | |
202 | |
203 _connection = value; | |
204 _closeConnection = false; | |
205 } | |
206 } | |
207 | |
208 [Obsolete] | |
209 protected virtual string GetConnectionString(IDbConnection connection) | |
210 { | |
211 return connection.ConnectionString; | |
212 } | |
213 | |
214 private void OpenConnection() | |
215 { | |
216 ExecuteOperation(OperationType.OpenConnection, _connection.Open); | |
217 _closeConnection = true; | |
218 } | |
219 | |
220 /// <summary> | |
221 /// Closes the connection to the database. | |
222 /// </summary> | |
223 /// <remarks> | |
224 /// The <b>Close</b> method rolls back any pending transactions | |
225 /// and then closes the connection. | |
226 /// </remarks> | |
227 /// <include file="Examples.xml" path='examples/db[@name="Close()"]/*' /> | |
228 /// <seealso cref="Dispose(bool)"/> | |
229 public void Close() | |
230 { | |
231 if (OnClosing != null) | |
232 OnClosing(this, EventArgs.Empty); | |
233 | |
234 if (_selectCommand != null) { _selectCommand.Dispose(); _selectCommand = null; } | |
235 if (_insertCommand != null) { _insertCommand.Dispose(); _insertCommand = null; } | |
236 if (_updateCommand != null) { _updateCommand.Dispose(); _updateCommand = null; } | |
237 if (_deleteCommand != null) { _deleteCommand.Dispose(); _deleteCommand = null; } | |
238 | |
239 if (_transaction != null && _closeTransaction) | |
240 { | |
241 ExecuteOperation(OperationType.DisposeTransaction, _transaction.Dispose); | |
242 _transaction = null; | |
243 } | |
244 | |
245 if (_connection != null && _closeConnection) | |
246 { | |
247 ExecuteOperation(OperationType.CloseConnection, _connection.Dispose); | |
248 _connection = null; | |
249 } | |
250 | |
251 if (OnClosed != null) | |
252 OnClosed(this, EventArgs.Empty); | |
253 } | |
254 | |
255 private bool? _isMarsEnabled; | |
256 public bool IsMarsEnabled | |
257 { | |
258 get | |
259 { | |
260 if (_isMarsEnabled == null) | |
261 _isMarsEnabled = DataProvider.IsMarsEnabled(Connection); | |
262 | |
263 return _isMarsEnabled.Value; | |
264 } | |
265 set { _isMarsEnabled = value; } | |
266 } | |
267 | |
268 #endregion | |
269 | |
270 #region Transactions | |
271 | |
272 private bool _closeTransaction = true; | |
273 private IDbTransaction _transaction; | |
274 /// <summary> | |
275 /// Gets the <see cref="IDbTransaction"/> used by this instance of the <see cref="DbManager"/>. | |
276 /// </summary> | |
277 /// <value> | |
278 /// The <see cref="IDbTransaction"/>. The default value is a null reference. | |
279 /// </value> | |
280 /// <remarks> | |
281 /// You have to call the <see cref="BeginTransaction()"/> method to begin a transaction. | |
282 /// </remarks> | |
283 /// <include file="Examples.xml" path='examples/db[@name="Transaction"]/*' /> | |
284 /// <seealso cref="BeginTransaction()"/> | |
285 public IDbTransaction Transaction | |
286 { | |
287 [DebuggerStepThrough] | |
288 get { return _transaction; } | |
289 } | |
290 | |
291 /// <summary> | |
292 /// Begins a database transaction. | |
293 /// </summary> | |
294 /// <remarks> | |
295 /// Once the transaction has completed, you must explicitly commit or roll back the transaction | |
296 /// by using the <see cref="System.Data.IDbTransaction.Commit"/>> or | |
297 /// <see cref="System.Data.IDbTransaction.Rollback"/> methods. | |
298 /// </remarks> | |
299 /// <include file="Examples.xml" path='examples/db[@name="BeginTransaction()"]/*' /> | |
300 /// <returns>This instance of the <see cref="DbManager"/>.</returns> | |
301 /// <seealso cref="Transaction"/> | |
302 public virtual DbManager BeginTransaction() | |
303 { | |
304 return BeginTransaction(IsolationLevel.ReadCommitted); | |
305 } | |
306 | |
307 /// <summary> | |
308 /// Begins a database transaction with the specified <see cref="IsolationLevel"/> value. | |
309 /// </summary> | |
310 /// <remarks> | |
311 /// Once the transaction has completed, you must explicitly commit or roll back the transaction | |
312 /// by using the <see cref="System.Data.IDbTransaction.Commit"/> or | |
313 /// <see cref="System.Data.IDbTransaction.Rollback"/> methods. | |
314 /// </remarks> | |
315 /// <include file="Examples.xml" path='examples/db[@name="BeginTransaction(IsolationLevel)"]/*' /> | |
316 /// <param name="il">One of the <see cref="IsolationLevel"/> values.</param> | |
317 /// <returns>This instance of the <see cref="DbManager"/>.</returns> | |
318 public virtual DbManager BeginTransaction(IsolationLevel il) | |
319 { | |
320 // If transaction is open, we dispose it, it will rollback all changes. | |
321 // | |
322 if (_transaction != null) | |
323 { | |
324 ExecuteOperation(OperationType.DisposeTransaction, _transaction.Dispose); | |
325 } | |
326 | |
327 // Create new transaction object. | |
328 // | |
329 _transaction = ExecuteOperation( | |
330 OperationType.BeginTransaction, | |
331 () => Connection.BeginTransaction(il)); | |
332 | |
333 _closeTransaction = true; | |
334 | |
335 // If the active command exists. | |
336 // | |
337 if (_selectCommand != null) _selectCommand.Transaction = _transaction; | |
338 if (_insertCommand != null) _insertCommand.Transaction = _transaction; | |
339 if (_updateCommand != null) _updateCommand.Transaction = _transaction; | |
340 if (_deleteCommand != null) _deleteCommand.Transaction = _transaction; | |
341 | |
342 return this; | |
343 } | |
344 | |
345 /// <summary> | |
346 /// Commits the database transaction. | |
347 /// </summary> | |
348 /// <returns>This instance of the <see cref="DbManager"/>.</returns> | |
349 public virtual DbManager CommitTransaction() | |
350 { | |
351 if (_transaction != null) | |
352 { | |
353 ExecuteOperation(OperationType.CommitTransaction, _transaction.Commit); | |
354 | |
355 if (_closeTransaction) | |
356 { | |
357 ExecuteOperation(OperationType.DisposeTransaction, _transaction.Dispose); | |
358 _transaction = null; | |
359 } | |
360 } | |
361 | |
362 return this; | |
363 } | |
364 | |
365 /// <summary> | |
366 /// Rolls back a transaction from a pending state. | |
367 /// </summary> | |
368 /// <returns>This instance of the <see cref="DbManager"/>.</returns> | |
369 public virtual DbManager RollbackTransaction() | |
370 { | |
371 if (_transaction != null) | |
372 { | |
373 ExecuteOperation(OperationType.RollbackTransaction, _transaction.Rollback); | |
374 | |
375 if (_closeTransaction) | |
376 { | |
377 ExecuteOperation(OperationType.DisposeTransaction, _transaction.Dispose); | |
378 _transaction = null; | |
379 } | |
380 } | |
381 | |
382 return this; | |
383 } | |
384 | |
385 #endregion | |
386 | |
387 #region Commands | |
388 | |
389 private IDbCommand _selectCommand; | |
390 /// <summary> | |
391 /// Gets the <see cref="IDbCommand"/> used by this instance of the <see cref="DbManager"/>. | |
392 /// </summary> | |
393 /// <value> | |
394 /// A <see cref="IDbCommand"/> used during executing query. | |
395 /// </value> | |
396 /// <remarks> | |
397 /// The <b>Command</b> can be used to access command parameters. | |
398 /// </remarks> | |
399 /// <include file="Examples.xml" path='examples/db[@name="Command"]/*' /> | |
400 public IDbCommand Command | |
401 { | |
402 [DebuggerStepThrough] | |
403 get { return SelectCommand; } | |
404 } | |
405 | |
406 /// <summary> | |
407 /// Gets the select <see cref="IDbCommand"/> used by this instance of the <see cref="DbManager"/>. | |
408 /// </summary> | |
409 /// <value> | |
410 /// A <see cref="IDbCommand"/> used during executing query. | |
411 /// </value> | |
412 /// <remarks> | |
413 /// The <b>SelectCommand</b> can be used to access select command parameters. | |
414 /// </remarks> | |
415 /// <include file="Examples.xml" path='examples/db[@name="Command"]/*' /> | |
416 public IDbCommand SelectCommand | |
417 { | |
418 [DebuggerStepThrough] | |
419 get { return _selectCommand = OnInitCommand(_selectCommand); } | |
420 } | |
421 | |
422 private IDbCommand _insertCommand; | |
423 /// <summary> | |
424 /// Gets the insert <see cref="IDbCommand"/> used by this instance of the <see cref="DbManager"/>. | |
425 /// </summary> | |
426 /// <value> | |
427 /// A <see cref="IDbCommand"/> used during executing query. | |
428 /// </value> | |
429 /// <remarks> | |
430 /// The <b>InsertCommand</b> can be used to access insert command parameters. | |
431 /// </remarks> | |
432 /// <include file="Examples.xml" path='examples/db[@name="Command"]/*' /> | |
433 public IDbCommand InsertCommand | |
434 { | |
435 [DebuggerStepThrough] | |
436 get { return _insertCommand = OnInitCommand(_insertCommand); } | |
437 } | |
438 | |
439 private IDbCommand _updateCommand; | |
440 /// <summary> | |
441 /// Gets the update <see cref="IDbCommand"/> used by this instance of the <see cref="DbManager"/>. | |
442 /// </summary> | |
443 /// <value> | |
444 /// A <see cref="IDbCommand"/> used during executing query. | |
445 /// </value> | |
446 /// <remarks> | |
447 /// The <b>UpdateCommand</b> can be used to access update command parameters. | |
448 /// </remarks> | |
449 /// <include file="Examples.xml" path='examples/db[@name="Command"]/*' /> | |
450 public IDbCommand UpdateCommand | |
451 { | |
452 [DebuggerStepThrough] | |
453 get { return _updateCommand = OnInitCommand(_updateCommand); } | |
454 } | |
455 | |
456 private IDbCommand _deleteCommand; | |
457 /// <summary> | |
458 /// Gets the delete <see cref="IDbCommand"/> used by this instance of the <see cref="DbManager"/>. | |
459 /// </summary> | |
460 /// <value> | |
461 /// A <see cref="IDbCommand"/> used during executing query. | |
462 /// </value> | |
463 /// <remarks> | |
464 /// The <b>DeleteCommand</b> can be used to access delete command parameters. | |
465 /// </remarks> | |
466 /// <include file="Examples.xml" path='examples/db[@name="Command"]/*' /> | |
467 public IDbCommand DeleteCommand | |
468 { | |
469 [DebuggerStepThrough] | |
470 get { return _deleteCommand = OnInitCommand(_deleteCommand); } | |
471 } | |
472 | |
473 /// <summary> | |
474 /// Initializes a command and raises the <see cref="InitCommand"/> event. | |
475 /// </summary> | |
476 protected virtual IDbCommand OnInitCommand(IDbCommand command) | |
477 { | |
478 if (command == null) | |
479 { | |
480 // Create a command object. | |
481 // | |
482 command = _dataProvider.CreateCommandObject(Connection); | |
483 | |
484 // If an active transaction exists. | |
485 // | |
486 if (Transaction != null) | |
487 { | |
488 command.Transaction = Transaction; | |
489 } | |
490 } | |
491 | |
492 if (CanRaiseEvents) | |
493 { | |
494 var handler = (InitCommandEventHandler)Events[_eventInitCommand]; | |
495 | |
496 if (handler != null) | |
497 handler(this, new InitCommandEventArgs(command)); | |
498 } | |
499 | |
500 return command; | |
501 } | |
502 | |
503 /// <summary> | |
504 /// Helper function. Creates the command object and sets command type and command text. | |
505 /// </summary> | |
506 /// <param name="commandAction">Command action.</param> | |
507 /// <param name="commandType">The <see cref="System.Data.CommandType"/> | |
508 /// (stored procedure, text, etc.)</param> | |
509 /// <param name="sql">The SQL statement.</param> | |
510 /// <returns>The command object.</returns> | |
511 private IDbCommand GetCommand(CommandAction commandAction, CommandType commandType, string sql) | |
512 { | |
513 var command = GetCommand(commandAction, commandType); | |
514 | |
515 command.Parameters.Clear(); | |
516 command.CommandType = commandType; | |
517 command.CommandText = sql; | |
518 | |
519 return command; | |
520 } | |
521 | |
522 #endregion | |
523 | |
524 #region Events | |
525 | |
526 public event EventHandler OnClosing; | |
527 public event EventHandler OnClosed; | |
528 | |
529 private static readonly object _eventBeforeOperation = new object(); | |
530 /// <summary> | |
531 /// Occurs when a server-side operation is about to start. | |
532 /// </summary> | |
533 public event OperationTypeEventHandler BeforeOperation | |
534 { | |
535 add { Events.AddHandler (_eventBeforeOperation, value); } | |
536 remove { Events.RemoveHandler(_eventBeforeOperation, value); } | |
537 } | |
538 | |
539 private static readonly object _eventAfterOperation = new object(); | |
540 /// <summary> | |
541 /// Occurs when a server-side operation is complete. | |
542 /// </summary> | |
543 public event OperationTypeEventHandler AfterOperation | |
544 { | |
545 add { Events.AddHandler (_eventAfterOperation, value); } | |
546 remove { Events.RemoveHandler(_eventAfterOperation, value); } | |
547 } | |
548 | |
549 private static readonly object _eventOperationException = new object(); | |
550 /// <summary> | |
551 /// Occurs when a server-side operation is failed to execute. | |
552 /// </summary> | |
553 public event OperationExceptionEventHandler OperationException | |
554 { | |
555 add { Events.AddHandler (_eventOperationException, value); } | |
556 remove { Events.RemoveHandler(_eventOperationException, value); } | |
557 } | |
558 | |
559 private static readonly object _eventInitCommand = new object(); | |
560 /// <summary> | |
561 /// Occurs when the <see cref="Command"/> is initializing. | |
562 /// </summary> | |
563 public event InitCommandEventHandler InitCommand | |
564 { | |
565 add { Events.AddHandler (_eventInitCommand, value); } | |
566 remove { Events.RemoveHandler(_eventInitCommand, value); } | |
567 } | |
568 | |
569 /// <summary> | |
570 /// Raises the <see cref="BeforeOperation"/> event. | |
571 /// </summary> | |
572 /// <param name="op">The <see cref="OperationType"/>.</param> | |
573 protected virtual void OnBeforeOperation(OperationType op) | |
574 { | |
575 if (CanRaiseEvents) | |
576 { | |
577 var handler = (OperationTypeEventHandler)Events[_eventBeforeOperation]; | |
578 if (handler != null) | |
579 handler(this, new OperationTypeEventArgs(op)); | |
580 } | |
581 } | |
582 | |
583 /// <summary> | |
584 /// Raises the <see cref="AfterOperation"/> event. | |
585 /// </summary> | |
586 /// <param name="op">The <see cref="OperationType"/>.</param> | |
587 protected virtual void OnAfterOperation(OperationType op) | |
588 { | |
589 if (CanRaiseEvents) | |
590 { | |
591 var handler = (OperationTypeEventHandler)Events[_eventAfterOperation]; | |
592 if (handler != null) | |
593 handler(this, new OperationTypeEventArgs(op)); | |
594 } | |
595 } | |
596 | |
597 /// <summary> | |
598 /// Raises the <see cref="OperationException"/> event. | |
599 /// </summary> | |
600 /// <param name="op">The <see cref="OperationType"/>.</param> | |
601 /// <param name="ex">The <see cref="Exception"/> occurred.</param> | |
602 protected virtual void OnOperationException(OperationType op, DataException ex) | |
603 { | |
604 if (CanRaiseEvents) | |
605 { | |
606 var handler = (OperationExceptionEventHandler)Events[_eventOperationException]; | |
607 if (handler != null) | |
608 handler(this, new OperationExceptionEventArgs(op, ex)); | |
609 } | |
610 | |
611 throw ex; | |
612 } | |
613 | |
614 #endregion | |
615 | |
616 #region Protected Methods | |
617 | |
618 private IDataReader ExecuteReaderInternal() | |
619 { | |
620 return ExecuteReader(CommandBehavior.Default); | |
621 } | |
622 | |
623 private IDataReader ExecuteReaderInternal(CommandBehavior commandBehavior) | |
624 { | |
625 return ExecuteOperation( | |
626 OperationType.ExecuteReader, | |
627 () => | |
628 _dataProvider.GetDataReader(_mappingSchema, SelectCommand.ExecuteReader(commandBehavior))); | |
629 } | |
630 | |
631 private int ExecuteNonQueryInternal() | |
632 { | |
633 return ExecuteOperation<int>(OperationType.ExecuteNonQuery, SelectCommand.ExecuteNonQuery); | |
634 } | |
635 | |
636 #endregion | |
637 | |
638 #region Parameters | |
639 | |
640 private IDbDataParameter[] CreateSpParameters(string spName, object[] parameterValues, bool openNewConnectionToDiscoverParameters) | |
641 { | |
642 // Pull the parameters for this stored procedure from | |
643 // the parameter cache (or discover them & populate the cache) | |
644 // | |
645 var spParameters = GetSpParameters(spName, true, openNewConnectionToDiscoverParameters); | |
646 | |
647 // DbParameters are bound by name, plain parameters by order | |
648 // | |
649 var dbParameters = false; | |
650 | |
651 if (parameterValues == null || parameterValues.Length == 0 || | |
652 parameterValues[0] is IDbDataParameter || parameterValues[0] is IDbDataParameter[]) | |
653 { | |
654 // The PrepareParameters method may add some additional parameters. | |
655 // | |
656 parameterValues = PrepareParameters(parameterValues); | |
657 | |
658 if (parameterValues == null || parameterValues.Length == 0) | |
659 return spParameters; | |
660 | |
661 dbParameters = true; | |
662 } | |
663 | |
664 if (spParameters == null/* || commandParameters.Length == 0*/) | |
665 { | |
666 spParameters = new IDbDataParameter[parameterValues.Length]; | |
667 | |
668 if (dbParameters) | |
669 parameterValues.CopyTo(spParameters, 0); | |
670 else | |
671 for (var i = 0; i < parameterValues.Length; i++) | |
672 spParameters[i] = Parameter("?", parameterValues[i]); | |
673 | |
674 return spParameters; | |
675 } | |
676 | |
677 if (dbParameters) | |
678 { | |
679 // If we receive an array of IDbDataParameter, | |
680 // we need to copy parameters to the IDbDataParameter[]. | |
681 // | |
682 foreach (var spParam in spParameters) | |
683 { | |
684 var spParamName = spParam.ParameterName; | |
685 var found = false; | |
686 | |
687 foreach (IDbDataParameter paramWithValue in parameterValues) | |
688 { | |
689 var parameterNamesEqual = _dataProvider.ParameterNamesEqual(spParamName, paramWithValue.ParameterName); | |
690 if (!parameterNamesEqual) | |
691 { | |
692 var convertedParameterName = | |
693 _dataProvider.Convert(paramWithValue.ParameterName, ConvertType.NameToSprocParameter).ToString(); | |
694 | |
695 parameterNamesEqual = _dataProvider.ParameterNamesEqual(spParamName, convertedParameterName); | |
696 } | |
697 | |
698 if (!parameterNamesEqual) continue; | |
699 | |
700 if (spParam.Direction != paramWithValue.Direction) | |
701 { | |
702 if (TraceSwitch.TraceWarning) | |
703 WriteTraceLine( | |
704 string.Format( | |
705 "Stored Procedure '{0}'. Parameter '{1}' has different direction '{2}'. Should be '{3}'.", | |
706 spName, spParamName, spParam.Direction, paramWithValue.Direction), | |
707 TraceSwitch.DisplayName); | |
708 | |
709 spParam.Direction = paramWithValue.Direction; | |
710 } | |
711 | |
712 if (spParam.Direction != ParameterDirection.Output) | |
713 spParam.Value = paramWithValue.Value; | |
714 | |
715 paramWithValue.ParameterName = spParamName; | |
716 found = true; | |
717 break; | |
718 } | |
719 | |
720 if (found == false && ( | |
721 spParam.Direction == ParameterDirection.Input || | |
722 spParam.Direction == ParameterDirection.InputOutput)) | |
723 { | |
724 if (TraceSwitch.TraceWarning) | |
725 WriteTraceLine( | |
726 string.Format("Stored Procedure '{0}'. Parameter '{1}' not assigned.", spName, spParamName), | |
727 TraceSwitch.DisplayName); | |
728 | |
729 spParam.SourceColumn = _dataProvider.Convert(spParamName, ConvertType.SprocParameterToName).ToString(); | |
730 } | |
731 } | |
732 } | |
733 else | |
734 { | |
735 // Assign the provided values to the parameters based on parameter order. | |
736 // | |
737 AssignParameterValues(spName, spParameters, parameterValues); | |
738 } | |
739 | |
740 return spParameters; | |
741 } | |
742 | |
743 ///<summary> | |
744 /// Creates an one-dimension array of <see cref="IDbDataParameter"/> | |
745 /// from any combination on IDbDataParameter, IDbDataParameter[] or null references. | |
746 /// Null references are stripped, arrays and single parameters are combined | |
747 /// into a new array. | |
748 ///</summary> | |
749 /// <remarks>When two or more parameters has the same name, | |
750 /// the first parameter is used, all the rest are ignored.</remarks> | |
751 ///<param name="parameters">Array of IDbDataParameter, IDbDataParameter[] or null references.</param> | |
752 ///<returns>An normalized array of <see cref="IDbDataParameter"/> without null references.</returns> | |
753 ///<exception cref="ArgumentException">The parameter <paramref name="parameters"/> | |
754 /// contains anything except IDbDataParameter, IDbDataParameter[] or null reference.</exception> | |
755 public virtual IDbDataParameter[] PrepareParameters(object[] parameters) | |
756 { | |
757 if (parameters == null || parameters.Length == 0) | |
758 return null; | |
759 | |
760 // Little optimization. | |
761 // Check if we have only one single ref parameter. | |
762 // | |
763 object refParam = null; | |
764 | |
765 foreach (var p in parameters) | |
766 if (p != null) | |
767 { | |
768 if (refParam != null) | |
769 { | |
770 refParam = null; | |
771 break; | |
772 } | |
773 | |
774 refParam = p; | |
775 } | |
776 | |
777 if (refParam is IDbDataParameter[]) | |
778 { | |
779 return (IDbDataParameter[])refParam; | |
780 } | |
781 | |
782 if (refParam is IDbDataParameter) | |
783 { | |
784 var oneParameterArray = new IDbDataParameter[1]; | |
785 oneParameterArray[0] = (IDbDataParameter)refParam; | |
786 return oneParameterArray; | |
787 } | |
788 | |
789 var list = new List<IDbDataParameter>(parameters.Length); | |
790 var hash = new Dictionary<string, IDbDataParameter>(parameters.Length); | |
791 | |
792 foreach (var o in parameters) | |
793 if (o is IDbDataParameter) | |
794 { | |
795 var p = (IDbDataParameter) o; | |
796 | |
797 if (!hash.ContainsKey(p.ParameterName)) | |
798 { | |
799 list.Add(p); | |
800 hash.Add(p.ParameterName, p); | |
801 } | |
802 } | |
803 else if (o is IDbDataParameter[]) | |
804 { | |
805 foreach (var p in (IDbDataParameter[]) o) | |
806 if (!hash.ContainsKey(p.ParameterName)) | |
807 { | |
808 list.Add(p); | |
809 hash.Add(p.ParameterName, p); | |
810 } | |
811 } | |
812 else if (o != null && o != DBNull.Value) | |
813 throw new ArgumentException( | |
814 Resources.DbManager_NotDbDataParameter, "parameters"); | |
815 | |
816 return list.ToArray(); | |
817 } | |
818 | |
819 /// <summary> | |
820 /// This method is used to attach array of <see cref="IDbDataParameter"/> to a <see cref="IDbCommand"/>. | |
821 /// </summary> | |
822 /// <param name="command">The command to which the parameters will be added</param> | |
823 /// <param name="commandParameters">An array of IDbDataParameters tho be added to command</param> | |
824 private void AttachParameters(IDbCommand command, IEnumerable<IDbDataParameter> commandParameters) | |
825 { | |
826 command.Parameters.Clear(); | |
827 | |
828 foreach (var p in commandParameters) | |
829 _dataProvider.AttachParameter(command, p); | |
830 } | |
831 | |
832 private static readonly Dictionary<string, IDbDataParameter[]> _paramCache = | |
833 new Dictionary<string, IDbDataParameter[]>(); | |
834 private static readonly object _paramCacheLock = new object(); | |
835 | |
836 /// <summary> | |
837 /// Resolve at run time the appropriate set of parameters for a stored procedure. | |
838 /// </summary> | |
839 /// <param name="spName">The name of the stored procedure.</param> | |
840 /// <param name="includeReturnValueParameter">Whether or not to include their return value parameter.</param> | |
841 /// <param name="openNewConnection"></param> | |
842 /// <returns></returns> | |
843 protected virtual IDbDataParameter[] DiscoverSpParameters(string spName, bool includeReturnValueParameter, bool openNewConnection) | |
844 { | |
845 var con = openNewConnection ? CloneConnection() : _connection; | |
846 | |
847 try | |
848 { | |
849 if (con.State == ConnectionState.Closed) | |
850 { | |
851 ExecuteOperation(OperationType.OpenConnection, con.Open); | |
852 if (!openNewConnection) | |
853 _closeConnection = true; | |
854 } | |
855 | |
856 using (var cmd = con.CreateCommand()) | |
857 { | |
858 cmd.CommandType = CommandType.StoredProcedure; | |
859 cmd.CommandText = spName; | |
860 | |
861 var res = ExecuteOperation(OperationType.DeriveParameters, () => _dataProvider.DeriveParameters(cmd)); | |
862 | |
863 if (openNewConnection) | |
864 ExecuteOperation(OperationType.CloseConnection, con.Close); | |
865 | |
866 if (res == false) | |
867 return null; | |
868 | |
869 if (includeReturnValueParameter == false) | |
870 { | |
871 // All known data providers always treat | |
872 // the return value as first parameter. | |
873 // | |
874 cmd.Parameters.RemoveAt(0); | |
875 } | |
876 | |
877 var discoveredParameters = new IDbDataParameter[cmd.Parameters.Count]; | |
878 | |
879 for (var i = 0; i < cmd.Parameters.Count; i++) | |
880 discoveredParameters[i] = (IDbDataParameter)cmd.Parameters[i]; | |
881 | |
882 return discoveredParameters; | |
883 } | |
884 } | |
885 finally | |
886 { | |
887 if (con != null && openNewConnection) | |
888 con.Dispose(); | |
889 } | |
890 } | |
891 | |
892 /// <summary> | |
893 /// Copies cached parameter array. | |
894 /// </summary> | |
895 /// <param name="originalParameters">The original parameter array.</param> | |
896 /// <returns>The result array.</returns> | |
897 private IDbDataParameter[] CloneParameters(IDbDataParameter[] originalParameters) | |
898 { | |
899 if (originalParameters == null) | |
900 return null; | |
901 | |
902 var clonedParameters = new IDbDataParameter[originalParameters.Length]; | |
903 | |
904 for (var i = 0; i < originalParameters.Length; i++) | |
905 clonedParameters[i] = _dataProvider.CloneParameter(originalParameters[i]); | |
906 | |
907 return clonedParameters; | |
908 } | |
909 | |
910 /// <summary> | |
911 /// Retrieves the set of parameters appropriate for the stored procedure. | |
912 /// </summary> | |
913 /// <remarks> | |
914 /// This method will query the database for this information, | |
915 /// and then store it in a cache for future requests. | |
916 /// </remarks> | |
917 /// <param name="spName">The name of the stored procedure.</param> | |
918 /// <param name="includeReturnValueParameter">A boolean value indicating | |
919 /// whether the return value parameter should be included in the results.</param> | |
920 /// <param name="openNewConnectionToDiscoverParameters"></param> | |
921 /// <returns>An array of the <see cref="IDbDataParameter"/>.</returns> | |
922 public IDbDataParameter[] GetSpParameters(string spName, bool includeReturnValueParameter, bool openNewConnectionToDiscoverParameters) | |
923 { | |
924 var key = string.Format("{0}:{1}:{2}", GetConnectionHash(), spName, includeReturnValueParameter); | |
925 | |
926 IDbDataParameter[] cachedParameters; | |
927 | |
928 // It is thread safe enought to check for a key and get its value without a lock. | |
929 // | |
930 if (!_paramCache.TryGetValue(key, out cachedParameters)) | |
931 { | |
932 lock (_paramCacheLock) | |
933 { | |
934 // There is a possible race condition since the operation may take a time. | |
935 // | |
936 if (!_paramCache.TryGetValue(key, out cachedParameters)) | |
937 { | |
938 cachedParameters = DiscoverSpParameters(spName, includeReturnValueParameter, openNewConnectionToDiscoverParameters); | |
939 _paramCache.Add(key, cachedParameters); | |
940 } | |
941 } | |
942 } | |
943 | |
944 return CloneParameters(cachedParameters); | |
945 } | |
946 | |
947 /// <summary> | |
948 /// This method assigns an array of values to an array of parameters. | |
949 /// </summary> | |
950 /// <param name="spName"></param> | |
951 /// <param name="commandParameters">array of IDbDataParameters to be assigned values</param> | |
952 /// <param name="parameterValues">array of objects holding the values to be assigned</param> | |
953 private void AssignParameterValues(string spName, IDbDataParameter[] commandParameters, object[] parameterValues) | |
954 { | |
955 if (commandParameters == null || parameterValues == null) | |
956 { | |
957 // Do nothing if we get no data. | |
958 // | |
959 return; | |
960 } | |
961 | |
962 var nValues = 0; | |
963 | |
964 // Iterate through the parameters, assigning the values from | |
965 // the corresponding position in the value array. | |
966 // | |
967 for (var index = 0; index < commandParameters.Length; index++) | |
968 { | |
969 var parameter = commandParameters[index]; | |
970 | |
971 if (_dataProvider.IsValueParameter(parameter)) | |
972 { | |
973 if (nValues >= parameterValues.Length) | |
974 throw new ArgumentException(string.Format("Parsing for {0} failed: {1}", spName, GetMissedColumnNames(index, commandParameters))); | |
975 | |
976 var value = parameterValues[nValues++]; | |
977 | |
978 _dataProvider.SetParameterValue(parameter, value ?? DBNull.Value); | |
979 } | |
980 } | |
981 | |
982 // We must have the same number of values as we pave parameters to put them in. | |
983 // | |
984 if (nValues != parameterValues.Length) | |
985 throw new ArgumentException(string.Format("Parsing for {0} failed: {1}", spName, GetExceedParameters(nValues, parameterValues))); | |
986 } | |
987 | |
988 string GetMissedColumnNames(int startIndex, IDbDataParameter[] commandParameters) | |
989 { | |
990 var columnNames = new List<string>(); | |
991 | |
992 for (var index = startIndex; index < commandParameters.Length; index++) | |
993 { | |
994 var parameter = commandParameters[index]; | |
995 | |
996 if (_dataProvider.IsValueParameter(parameter)) | |
997 { | |
998 columnNames.Add(string.Format("{0} {{{1}}}", parameter.ParameterName, parameter.DbType)); | |
999 } | |
1000 } | |
1001 | |
1002 #if FW4 | |
1003 return "Missed columns: " + string.Join(", ", columnNames); | |
1004 #else | |
1005 return "Missed columns: " + string.Join(", ", columnNames.ToArray()); | |
1006 #endif | |
1007 } | |
1008 | |
1009 static string GetExceedParameters(int startIndex, object[] parameterValues) | |
1010 { | |
1011 var columnNames = new List<string>(); | |
1012 | |
1013 for (var index = startIndex; index < parameterValues.Length; index++) | |
1014 { | |
1015 var parameter = parameterValues[index]; | |
1016 columnNames.Add( | |
1017 parameter == null | |
1018 ? "<null>" | |
1019 : string.Format("{0} {{{1}}}", parameter, parameter.GetType().Name)); | |
1020 } | |
1021 | |
1022 #if FW4 | |
1023 return "Exceed parameters: " + string.Join(", ", columnNames); | |
1024 #else | |
1025 return "Exceed parameters: " + string.Join(", ", columnNames.ToArray()); | |
1026 #endif | |
1027 } | |
1028 | |
1029 /// <overloads> | |
1030 /// Assigns a business object to command parameters. | |
1031 /// </overloads> | |
1032 /// <summary> | |
1033 /// Assigns the <see cref="DataRow"/> to command parameters. | |
1034 /// </summary> | |
1035 /// <include file="Examples1.xml" path='examples/db[@name="AssignParameterValues(DataRow)"]/*' /> | |
1036 /// <remarks> | |
1037 /// The method is used in addition to the <see cref="CreateParameters(object,IDbDataParameter[])"/> method. | |
1038 /// </remarks> | |
1039 /// <param name="dataRow">The <see cref="DataRow"/> to assign.</param> | |
1040 /// <returns>This instance of the <see cref="DbManager"/>.</returns> | |
1041 public DbManager AssignParameterValues(DataRow dataRow) | |
1042 { | |
1043 if (dataRow == null) | |
1044 throw new ArgumentNullException("dataRow"); | |
1045 | |
1046 foreach (DataColumn c in dataRow.Table.Columns) | |
1047 if (c.AutoIncrement == false && c.ReadOnly == false) | |
1048 { | |
1049 var o = dataRow[c.ColumnName]; | |
1050 var name = _dataProvider.Convert(c.ColumnName, GetConvertTypeToParameter()).ToString(); | |
1051 | |
1052 Parameter(name).Value = | |
1053 c.AllowDBNull && _mappingSchema.IsNull(o) ? DBNull.Value : o; | |
1054 } | |
1055 | |
1056 if (_prepared) | |
1057 InitParameters(CommandAction.Select); | |
1058 | |
1059 return this; | |
1060 } | |
1061 | |
1062 /// <summary> | |
1063 /// Assigns a business object to command parameters. | |
1064 /// </summary> | |
1065 /// <remarks> | |
1066 /// The method is used in addition to the <see cref="CreateParameters(object,IDbDataParameter[])"/> method. | |
1067 /// </remarks> | |
1068 /// <include file="Examples1.xml" path='examples/db[@name="AssignParameterValues(object)"]/*' /> | |
1069 /// <param name="obj">An object to assign.</param> | |
1070 /// <returns>This instance of the <see cref="DbManager"/>.</returns> | |
1071 public DbManager AssignParameterValues(object obj) | |
1072 { | |
1073 if (obj == null) | |
1074 throw new ArgumentNullException("obj"); | |
1075 | |
1076 var om = _mappingSchema.GetObjectMapper(obj.GetType()); | |
1077 | |
1078 foreach (MemberMapper mm in om) | |
1079 { | |
1080 var name = _dataProvider.Convert(mm.Name, GetConvertTypeToParameter()).ToString(); | |
1081 | |
1082 if (Command.Parameters.Contains(name)) | |
1083 { | |
1084 var value = mm.GetValue(obj); | |
1085 | |
1086 _dataProvider.SetParameterValue( | |
1087 Parameter(name), | |
1088 value == null || mm.MapMemberInfo.Nullable && _mappingSchema.IsNull(value)? | |
1089 DBNull.Value: value); | |
1090 } | |
1091 } | |
1092 | |
1093 if (_prepared) | |
1094 InitParameters(CommandAction.Select); | |
1095 | |
1096 return this; | |
1097 } | |
1098 | |
1099 private static Array SortArray(Array array, IComparer comparer) | |
1100 { | |
1101 if (array == null) | |
1102 return null; | |
1103 | |
1104 var arrayClone = (Array)array.Clone(); | |
1105 | |
1106 Array.Sort(arrayClone, comparer); | |
1107 | |
1108 return arrayClone; | |
1109 } | |
1110 | |
1111 /// <summary> | |
1112 /// Creates an array of parameters from the <see cref="DataRow"/> object. | |
1113 /// </summary> | |
1114 /// <remarks> | |
1115 /// The method can take an additional parameter list, | |
1116 /// which can be created by using the same method. | |
1117 /// </remarks> | |
1118 /// <include file="Examples.xml" path='examples/db[@name="CreateParameters(DataRow,IDbDataParameter[])"]/*' /> | |
1119 /// <param name="dataRow">The <see cref="DataRow"/> to create parameters.</param> | |
1120 /// <param name="commandParameters">An array of parameters to be added to the result array.</param> | |
1121 /// <returns>An array of parameters.</returns> | |
1122 public IDbDataParameter[] CreateParameters( | |
1123 DataRow dataRow, params IDbDataParameter[] commandParameters) | |
1124 { | |
1125 return CreateParameters(dataRow, null, null, null, commandParameters); | |
1126 } | |
1127 | |
1128 /// <summary> | |
1129 /// Creates an array of parameters from the <see cref="DataRow"/> object. | |
1130 /// </summary> | |
1131 /// <remarks> | |
1132 /// The method can take an additional parameter list, | |
1133 /// which can be created by using the same method. | |
1134 /// </remarks> | |
1135 /// <include file="Examples.xml" path='examples/db[@name="CreateParameters(DataRow,IDbDataParameter[])"]/*' /> | |
1136 /// <param name="dataRow">The <see cref="DataRow"/> to create parameters.</param> | |
1137 /// <param name="outputParameters">Output parameters names.</param> | |
1138 /// <param name="inputOutputParameters">InputOutput parameters names.</param> | |
1139 /// <param name="ignoreParameters">Parameters names to skip.</param> | |
1140 /// <param name="commandParameters">An array of parameters to be added to the result array.</param> | |
1141 /// <returns>An array of parameters.</returns> | |
1142 public IDbDataParameter[] CreateParameters( | |
1143 DataRow dataRow, | |
1144 string[] outputParameters, | |
1145 string[] inputOutputParameters, | |
1146 string[] ignoreParameters, | |
1147 params IDbDataParameter[] commandParameters) | |
1148 { | |
1149 if (dataRow == null) | |
1150 throw new ArgumentNullException("dataRow"); | |
1151 | |
1152 var paramList = new ArrayList(); | |
1153 IComparer comparer = CaseInsensitiveComparer.Default; | |
1154 | |
1155 outputParameters = (string[])SortArray(outputParameters, comparer); | |
1156 inputOutputParameters = (string[])SortArray(inputOutputParameters, comparer); | |
1157 ignoreParameters = (string[])SortArray(ignoreParameters, comparer); | |
1158 | |
1159 foreach (DataColumn c in dataRow.Table.Columns) | |
1160 { | |
1161 if (ignoreParameters != null && Array.BinarySearch(ignoreParameters, c.ColumnName, comparer) >= 0) | |
1162 continue; | |
1163 | |
1164 if (c.AutoIncrement || c.ReadOnly) | |
1165 continue; | |
1166 | |
1167 var name = _dataProvider.Convert(c.ColumnName, GetConvertTypeToParameter()).ToString(); | |
1168 var parameter = | |
1169 c.AllowDBNull | |
1170 ? NullParameter(name, dataRow[c.ColumnName]) | |
1171 : Parameter (name, dataRow[c.ColumnName]); | |
1172 | |
1173 if (outputParameters != null && Array.BinarySearch(outputParameters, c.ColumnName, comparer) >= 0) | |
1174 parameter.Direction = ParameterDirection.Output; | |
1175 else if (inputOutputParameters != null && Array.BinarySearch(inputOutputParameters, c.ColumnName, comparer) >= 0) | |
1176 parameter.Direction = ParameterDirection.InputOutput; | |
1177 | |
1178 paramList.Add(parameter); | |
1179 } | |
1180 | |
1181 if (commandParameters != null) | |
1182 paramList.AddRange(commandParameters); | |
1183 | |
1184 return (IDbDataParameter[])paramList.ToArray(typeof(IDbDataParameter)); | |
1185 } | |
1186 | |
1187 /// <summary> | |
1188 /// Creates an array of parameters from a business object. | |
1189 /// </summary> | |
1190 /// <remarks> | |
1191 /// The method can take an additional parameter list, | |
1192 /// which can be created by using the same method. | |
1193 /// </remarks> | |
1194 /// <include file="Examples.xml" path='examples/db[@name="CreateParameters(object,IDbDataParameter[])"]/*' /> | |
1195 /// <param name="obj">An object.</param> | |
1196 /// <param name="commandParameters">An array of parameters to be added to the result array.</param> | |
1197 /// <returns>An array of parameters.</returns> | |
1198 public IDbDataParameter[] CreateParameters( | |
1199 object obj, | |
1200 params IDbDataParameter[] commandParameters) | |
1201 { | |
1202 return CreateParameters(obj, null, null, null, commandParameters); | |
1203 } | |
1204 | |
1205 /// <summary> | |
1206 /// Creates an array of parameters from a business object. | |
1207 /// </summary> | |
1208 /// <remarks> | |
1209 /// The method can take an additional parameter list, | |
1210 /// which can be created by using the same method. | |
1211 /// </remarks> | |
1212 /// <include file="Examples.xml" path='examples/db[@name="CreateParameters(object,IDbDataParameter[])"]/*' /> | |
1213 /// <param name="obj">An object.</param> | |
1214 /// <param name="outputParameters">Output parameters names.</param> | |
1215 /// <param name="inputOutputParameters">InputOutput parameters names.</param> | |
1216 /// <param name="ignoreParameters">Parameters names to skip.</param> | |
1217 /// <param name="commandParameters">An array of parameters to be added to the result array.</param> | |
1218 /// <returns>An array of parameters.</returns> | |
1219 public IDbDataParameter[] CreateParameters( | |
1220 object obj, | |
1221 string[] outputParameters, | |
1222 string[] inputOutputParameters, | |
1223 string[] ignoreParameters, | |
1224 params IDbDataParameter[] commandParameters) | |
1225 { | |
1226 if (obj == null) | |
1227 throw new ArgumentNullException("obj"); | |
1228 | |
1229 var isType = obj is Type; | |
1230 var type = isType? (Type)obj: obj.GetType(); | |
1231 var om = _mappingSchema.GetObjectMapper(type); | |
1232 var paramList = new ArrayList(); | |
1233 var comparer = CaseInsensitiveComparer.Default; | |
1234 | |
1235 outputParameters = (string[])SortArray(outputParameters, comparer); | |
1236 inputOutputParameters = (string[])SortArray(inputOutputParameters, comparer); | |
1237 ignoreParameters = (string[])SortArray(ignoreParameters, comparer); | |
1238 | |
1239 foreach (MemberMapper mm in om) | |
1240 { | |
1241 if (ignoreParameters != null && Array.BinarySearch(ignoreParameters, mm.Name, comparer) >= 0) | |
1242 continue; | |
1243 | |
1244 var value = isType? null: mm.GetValue(obj); | |
1245 var name = _dataProvider.Convert(mm.Name, GetConvertTypeToParameter()).ToString(); | |
1246 | |
1247 var parameter = | |
1248 value == null ? | |
1249 NullParameter(name, value, mm.MapMemberInfo.NullValue) : | |
1250 (mm.DbType != DbType.Object) ? | |
1251 Parameter(name, value, mm.DbType): | |
1252 Parameter(name, value); | |
1253 | |
1254 if (outputParameters != null && Array.BinarySearch(outputParameters, mm.Name, comparer) >= 0) | |
1255 parameter.Direction = ParameterDirection.Output; | |
1256 else if (inputOutputParameters != null && Array.BinarySearch(inputOutputParameters, mm.Name, comparer) >= 0) | |
1257 parameter.Direction = ParameterDirection.InputOutput; | |
1258 | |
1259 paramList.Add(parameter); | |
1260 } | |
1261 | |
1262 if (commandParameters != null) | |
1263 paramList.AddRange(commandParameters); | |
1264 | |
1265 return (IDbDataParameter[])paramList.ToArray(typeof(IDbDataParameter)); | |
1266 } | |
1267 | |
1268 /// <summary> | |
1269 /// Maps all parameters returned from the server to all given objects. | |
1270 /// </summary> | |
1271 /// <param name="returnValueMember">Name of a <see cref="MemberMapper"/> to map return value.</param> | |
1272 /// <param name="obj">An <see cref="System.Object"/> to map from command parameters.</param> | |
1273 public void MapOutputParameters( | |
1274 string returnValueMember, | |
1275 object obj) | |
1276 { | |
1277 var dest = _mappingSchema.GetDataDestination(obj); | |
1278 | |
1279 foreach (IDbDataParameter parameter in Command.Parameters) | |
1280 { | |
1281 var ordinal = -1; | |
1282 | |
1283 switch (parameter.Direction) | |
1284 { | |
1285 case ParameterDirection.InputOutput: | |
1286 case ParameterDirection.Output: | |
1287 ordinal = dest.GetOrdinal( | |
1288 _dataProvider.Convert(parameter.ParameterName, ConvertType.SprocParameterToName).ToString()); | |
1289 break; | |
1290 | |
1291 case ParameterDirection.ReturnValue: | |
1292 | |
1293 if (returnValueMember != null) | |
1294 { | |
1295 if (!returnValueMember.StartsWith("@") && dest is ObjectMapper) | |
1296 { | |
1297 var om = (ObjectMapper) dest; | |
1298 var ma = om.TypeAccessor[returnValueMember]; | |
1299 | |
1300 if (ma != null) | |
1301 { | |
1302 ma.SetValue(obj, _mappingSchema.ConvertChangeType(parameter.Value, ma.Type)); | |
1303 continue; | |
1304 } | |
1305 } | |
1306 else | |
1307 returnValueMember = returnValueMember.Substring(1); | |
1308 | |
1309 ordinal = dest.GetOrdinal(returnValueMember); | |
1310 } | |
1311 | |
1312 break; | |
1313 } | |
1314 | |
1315 if (ordinal >= 0) | |
1316 dest.SetValue(obj, ordinal, _mappingSchema.ConvertChangeType(parameter.Value, dest.GetFieldType(ordinal))); | |
1317 } | |
1318 } | |
1319 | |
1320 /// <summary> | |
1321 /// Maps all parameters returned from the server to an object. | |
1322 /// </summary> | |
1323 /// <param name="obj">An <see cref="System.Object"/> to map from command parameters.</param> | |
1324 public void MapOutputParameters(object obj) | |
1325 { | |
1326 MapOutputParameters(null, obj); | |
1327 } | |
1328 | |
1329 /// <summary> | |
1330 /// Maps all parameters returned from the server to all given objects. | |
1331 /// </summary> | |
1332 /// <param name="returnValueMember">Name of the member used to map the | |
1333 /// return value. Can be null.</param> | |
1334 /// <param name="objects">An array of <see cref="System.Object"/> to map | |
1335 /// from command parameters.</param> | |
1336 public void MapOutputParameters(string returnValueMember, params object[] objects) | |
1337 { | |
1338 if (objects == null) | |
1339 return; | |
1340 | |
1341 foreach (var obj in objects) | |
1342 MapOutputParameters(returnValueMember, obj); | |
1343 } | |
1344 | |
1345 /// <summary> | |
1346 /// Maps all parameters returned from the server to an object. | |
1347 /// </summary> | |
1348 /// <param name="objects">An array of <see cref="System.Object"/> to map | |
1349 /// from command parameters.</param> | |
1350 public void MapOutputParameters(params object[] objects) | |
1351 { | |
1352 MapOutputParameters(null, objects); | |
1353 } | |
1354 | |
1355 /// <overloads> | |
1356 /// Adds a parameter to the <see cref="Command"/> or returns existing one. | |
1357 /// </overloads> | |
1358 /// <summary> | |
1359 /// Returns an existing parameter. | |
1360 /// </summary> | |
1361 /// <remarks> | |
1362 /// The method can be used to retrieve return and output parameters. | |
1363 /// </remarks> | |
1364 /// <include file="Examples1.xml" path='examples/db[@name="Parameter(string)"]/*' /> | |
1365 /// <param name="parameterName">The name of the parameter.</param> | |
1366 /// <returns>The <see cref="IDbDataParameter"/> object.</returns> | |
1367 public IDbDataParameter Parameter(string parameterName) | |
1368 { | |
1369 return _dataProvider.GetParameter(Command, parameterName); | |
1370 } | |
1371 | |
1372 /// <summary> | |
1373 /// Adds an input parameter to the <see cref="Command"/>. | |
1374 /// </summary> | |
1375 /// <remarks> | |
1376 /// The method creates a parameter with the | |
1377 /// <see cref="System.Data.ParameterDirection">ParameterDirection.Input</see> type. | |
1378 /// </remarks> | |
1379 /// <include file="Examples1.xml" path='examples/db[@name="Parameter(string,object)"]/*' /> | |
1380 /// <param name="parameterName">The name of the parameter.</param> | |
1381 /// <param name="value">The <see cref="System.Object"/> | |
1382 /// that is the value of the parameter.</param> | |
1383 /// <returns>The <see cref="IDbDataParameter"/> object.</returns> | |
1384 public IDbDataParameter Parameter(string parameterName, object value) | |
1385 { | |
1386 return Parameter(ParameterDirection.Input, parameterName, value); | |
1387 } | |
1388 | |
1389 /// <summary> | |
1390 /// Adds an input parameter to the <see cref="Command"/>. | |
1391 /// </summary> | |
1392 /// <remarks> | |
1393 /// The method creates a parameter with the | |
1394 /// <see cref="System.Data.ParameterDirection">ParameterDirection.Input</see> type. | |
1395 /// </remarks> | |
1396 /// <param name="parameterName">The name of the parameter.</param> | |
1397 /// <param name="dbType">One of the <see cref="DbType"/> values.</param> | |
1398 /// <returns>The <see cref="IDbDataParameter"/> object.</returns> | |
1399 public IDbDataParameter Parameter(string parameterName, DbType dbType) | |
1400 { | |
1401 return Parameter(ParameterDirection.Input, parameterName, dbType); | |
1402 } | |
1403 | |
1404 /// <summary> | |
1405 /// Adds an input parameter to the <see cref="Command"/>. | |
1406 /// </summary> | |
1407 /// <remarks> | |
1408 /// The method creates a parameter with the | |
1409 /// <see cref="System.Data.ParameterDirection">ParameterDirection.Input</see> type. | |
1410 /// </remarks> | |
1411 /// <param name="parameterName">The name of the parameter.</param> | |
1412 /// <param name="dbType">One of the <see cref="DbType"/> values.</param> | |
1413 /// <param name="size">Size of the parameter.</param> | |
1414 /// <returns>The <see cref="IDbDataParameter"/> object.</returns> | |
1415 public IDbDataParameter Parameter(string parameterName, DbType dbType, int size) | |
1416 { | |
1417 return Parameter(ParameterDirection.Input, parameterName, dbType, size); | |
1418 } | |
1419 | |
1420 /// <summary> | |
1421 /// Adds an input parameter to the <see cref="Command"/>. | |
1422 /// </summary> | |
1423 /// <remarks> | |
1424 /// The method creates a parameter with the | |
1425 /// <see cref="System.Data.ParameterDirection">ParameterDirection.Input</see> type. | |
1426 /// If the parameter is null, it's converted to <see cref="DBNull"/>.<see cref="DBNull.Value"/>. | |
1427 /// </remarks> | |
1428 /// <include file="Examples1.xml" path='examples/db[@name="NullParameter(string,object)"]/*' /> | |
1429 /// <param name="parameterName">The name of the parameter.</param> | |
1430 /// <param name="value">The <see cref="System.Object"/> | |
1431 /// that is the value of the parameter.</param> | |
1432 /// <returns>The <see cref="IDbDataParameter"/> object.</returns> | |
1433 public IDbDataParameter NullParameter(string parameterName, object value) | |
1434 { | |
1435 if (_mappingSchema.IsNull(value)) | |
1436 @value = DBNull.Value; | |
1437 | |
1438 return Parameter(ParameterDirection.Input, parameterName, value); | |
1439 } | |
1440 | |
1441 /// <summary> | |
1442 /// Adds an input parameter to the <see cref="Command"/>. | |
1443 /// </summary> | |
1444 /// <remarks> | |
1445 /// The method creates a parameter with the | |
1446 /// <see cref="System.Data.ParameterDirection">ParameterDirection.Input</see> type. | |
1447 /// </remarks> | |
1448 /// <param name="parameterName">The name of the parameter.</param> | |
1449 /// <param name="value">The <see cref="System.Object"/> | |
1450 /// that is the value of the parameter.</param> | |
1451 /// <param name="nullValue">The null equivalent to compare with the value.</param> | |
1452 /// <returns>The <see cref="IDbDataParameter"/> object.</returns> | |
1453 public IDbDataParameter NullParameter(string parameterName, object value, object nullValue) | |
1454 { | |
1455 if (value == null || value.Equals(nullValue)) | |
1456 @value = DBNull.Value; | |
1457 | |
1458 return Parameter(ParameterDirection.Input, parameterName, value); | |
1459 } | |
1460 | |
1461 /// <summary> | |
1462 /// Adds an input parameter to the <see cref="Command"/>. | |
1463 /// </summary> | |
1464 /// <remarks> | |
1465 /// The method creates a parameter with the | |
1466 /// <see cref="System.Data.ParameterDirection">ParameterDirection.Input</see> type. | |
1467 /// </remarks> | |
1468 /// <param name="parameterName">The name of the parameter.</param> | |
1469 /// <param name="value">The <see cref="System.Object"/> | |
1470 /// that is the value of the parameter.</param> | |
1471 /// <returns>The <see cref="IDbDataParameter"/> object.</returns> | |
1472 public IDbDataParameter InputParameter(string parameterName, object value) | |
1473 { | |
1474 return Parameter(ParameterDirection.Input, parameterName, value); | |
1475 } | |
1476 | |
1477 /// <summary> | |
1478 /// Adds an output parameter to the <see cref="Command"/>. | |
1479 /// </summary> | |
1480 /// <remarks> | |
1481 /// The method creates a parameter with the | |
1482 /// <see cref="System.Data.ParameterDirection">ParameterDirection.Output</see> type. | |
1483 /// </remarks> | |
1484 /// <param name="parameterName">The name of the parameter.</param> | |
1485 /// <param name="value">The <see cref="System.Object"/> | |
1486 /// that is the value of the parameter.</param> | |
1487 /// <returns>The <see cref="IDbDataParameter"/> object.</returns> | |
1488 public IDbDataParameter OutputParameter(string parameterName, object value) | |
1489 { | |
1490 return Parameter(ParameterDirection.Output, parameterName, value); | |
1491 } | |
1492 | |
1493 /// <summary> | |
1494 /// Adds an output parameter to the <see cref="Command"/>. | |
1495 /// </summary> | |
1496 /// <remarks> | |
1497 /// The method creates a parameter with the | |
1498 /// <see cref="System.Data.ParameterDirection">ParameterDirection.Output</see> type. | |
1499 /// </remarks> | |
1500 /// <param name="parameterName">The name of the parameter.</param> | |
1501 /// <param name="dbType">One of the <see cref="DbType"/> values.</param> | |
1502 /// <returns>The <see cref="IDbDataParameter"/> object.</returns> | |
1503 public IDbDataParameter OutputParameter(string parameterName, DbType dbType) | |
1504 { | |
1505 return Parameter(ParameterDirection.Output, parameterName, dbType); | |
1506 } | |
1507 | |
1508 /// <summary> | |
1509 /// Adds an output parameter to the <see cref="Command"/>. | |
1510 /// </summary> | |
1511 /// <remarks> | |
1512 /// The method creates a parameter with the | |
1513 /// <see cref="System.Data.ParameterDirection">ParameterDirection.Output</see> type. | |
1514 /// </remarks> | |
1515 /// <param name="parameterName">The name of the parameter.</param> | |
1516 /// <param name="dbType">One of the <see cref="DbType"/> values.</param> | |
1517 /// <param name="size">Size of the parameter.</param> | |
1518 /// <returns>The <see cref="IDbDataParameter"/> object.</returns> | |
1519 public IDbDataParameter OutputParameter(string parameterName, DbType dbType, int size) | |
1520 { | |
1521 return Parameter(ParameterDirection.Output, parameterName, dbType, size); | |
1522 } | |
1523 | |
1524 /// <summary> | |
1525 /// Adds an input-output parameter to the <see cref="Command"/>. | |
1526 /// </summary> | |
1527 /// <remarks> | |
1528 /// The method creates a parameter with the | |
1529 /// <see cref="System.Data.ParameterDirection">ParameterDirection.InputOutput</see> type. | |
1530 /// </remarks> | |
1531 /// <param name="parameterName">The name of the parameter.</param> | |
1532 /// <param name="value">The <see cref="System.Object"/> | |
1533 /// that is the value of the parameter.</param> | |
1534 /// <returns>The <see cref="IDbDataParameter"/> object.</returns> | |
1535 public IDbDataParameter InputOutputParameter(string parameterName, object value) | |
1536 { | |
1537 return Parameter(ParameterDirection.InputOutput,parameterName, value); | |
1538 } | |
1539 | |
1540 /// <summary> | |
1541 /// Adds a return value parameter to the <see cref="Command"/>. | |
1542 /// </summary> | |
1543 /// <remarks> | |
1544 /// The method creates a parameter with the | |
1545 /// <see cref="System.Data.ParameterDirection">ParameterDirection.ReturnValue</see> type. | |
1546 /// </remarks> | |
1547 /// <param name="parameterName">The name of the parameter.</param> | |
1548 /// <returns>The <see cref="IDbDataParameter"/> object.</returns> | |
1549 public IDbDataParameter ReturnValue(string parameterName) | |
1550 { | |
1551 return Parameter(ParameterDirection.ReturnValue, parameterName, null); | |
1552 } | |
1553 | |
1554 /// <summary> | |
1555 /// Adds a parameter to the <see cref="Command"/>. | |
1556 /// </summary> | |
1557 /// <remarks> | |
1558 /// The method creates a parameter with the specified | |
1559 /// <see cref="System.Data.ParameterDirection"/> type. | |
1560 /// </remarks> | |
1561 /// <param name="parameterDirection">One of the <see cref="System.Data.ParameterDirection"/> values.</param> | |
1562 /// <param name="parameterName">The name of the parameter.</param> | |
1563 /// <param name="value">The <see cref="System.Object"/> | |
1564 /// that is the value of the parameter.</param> | |
1565 /// <returns>The <see cref="IDbDataParameter"/> object.</returns> | |
1566 public IDbDataParameter Parameter( | |
1567 ParameterDirection parameterDirection, | |
1568 string parameterName, | |
1569 object value) | |
1570 { | |
1571 var parameter = _dataProvider.CreateParameterObject(Command); | |
1572 | |
1573 parameter.ParameterName = parameterName; | |
1574 parameter.Direction = parameterDirection; | |
1575 | |
1576 _dataProvider.SetParameterValue(parameter, value ?? DBNull.Value); | |
1577 | |
1578 return parameter; | |
1579 } | |
1580 | |
1581 /// <summary> | |
1582 /// Adds a parameter to the <see cref="Command"/>. | |
1583 /// </summary> | |
1584 /// <remarks> | |
1585 /// The method creates a parameter with the specified | |
1586 /// <see cref="System.Data.ParameterDirection"/> type. | |
1587 /// </remarks> | |
1588 /// <param name="parameterDirection">One of the <see cref="System.Data.ParameterDirection"/> values.</param> | |
1589 /// <param name="parameterName">The name of the parameter.</param> | |
1590 /// <param name="value">The <see cref="System.Object"/> | |
1591 /// that is the value of the parameter.</param> | |
1592 /// <param name="dbType">One of the <seealso cref="DbType"/> values.</param> | |
1593 /// <returns>The <see cref="IDbDataParameter"/> object.</returns> | |
1594 public IDbDataParameter Parameter( | |
1595 ParameterDirection parameterDirection, | |
1596 string parameterName, | |
1597 object value, | |
1598 DbType dbType) | |
1599 { | |
1600 var parameter = _dataProvider.CreateParameterObject(Command); | |
1601 | |
1602 parameter.ParameterName = parameterName; | |
1603 parameter.Direction = parameterDirection; | |
1604 parameter.DbType = _dataProvider.GetParameterDbType(dbType); | |
1605 | |
1606 _dataProvider.SetParameterValue(parameter, value ?? DBNull.Value); | |
1607 | |
1608 return parameter; | |
1609 } | |
1610 | |
1611 /// <summary> | |
1612 /// Adds an input parameter to the <see cref="Command"/>. | |
1613 /// </summary> | |
1614 /// <param name="parameterName">The name of the parameter.</param> | |
1615 /// <param name="value">The <see cref="System.Object"/> | |
1616 /// that is the value of the parameter.</param> | |
1617 /// <param name="dbType">One of the <seealso cref="DbType"/> values.</param> | |
1618 /// <returns>The <see cref="IDbDataParameter"/> object.</returns> | |
1619 public IDbDataParameter Parameter( | |
1620 string parameterName, | |
1621 object value, | |
1622 DbType dbType) | |
1623 { | |
1624 return Parameter(ParameterDirection.Input, parameterName, value, dbType); | |
1625 } | |
1626 | |
1627 /// <summary> | |
1628 /// Adds a parameter to the <see cref="Command"/>. | |
1629 /// </summary> | |
1630 /// <remarks> | |
1631 /// The method creates a parameter with the specified | |
1632 /// <see cref="System.Data.ParameterDirection"/> type. | |
1633 /// </remarks> | |
1634 /// <param name="parameterDirection">One of the <see cref="System.Data.ParameterDirection"/> values.</param> | |
1635 /// <param name="parameterName">The name of the parameter.</param> | |
1636 /// <param name="value">The <see cref="System.Object"/> | |
1637 /// that is the value of the parameter.</param> | |
1638 /// <param name="dbType">One of the <seealso cref="DbType"/> values.</param> | |
1639 /// <param name="size">Size of the parameter.</param> | |
1640 /// <returns>The <see cref="IDbDataParameter"/> object.</returns> | |
1641 public IDbDataParameter Parameter( | |
1642 ParameterDirection parameterDirection, | |
1643 string parameterName, | |
1644 object value, | |
1645 DbType dbType, | |
1646 int size) | |
1647 { | |
1648 var parameter = _dataProvider.CreateParameterObject(Command); | |
1649 | |
1650 parameter.ParameterName = parameterName; | |
1651 parameter.Direction = parameterDirection; | |
1652 parameter.DbType = dbType; | |
1653 parameter.Size = size; | |
1654 | |
1655 _dataProvider.SetParameterValue(parameter, value); | |
1656 | |
1657 return parameter; | |
1658 } | |
1659 | |
1660 /// <summary> | |
1661 /// Adds a parameter to the <see cref="Command"/>. | |
1662 /// </summary> | |
1663 /// <remarks> | |
1664 /// The method creates a parameter with the specified | |
1665 /// <see cref="System.Data.ParameterDirection"/> type. | |
1666 /// </remarks> | |
1667 /// <param name="parameterDirection">One of the <see cref="System.Data.ParameterDirection"/> values.</param> | |
1668 /// <param name="parameterName">The name of the parameter.</param> | |
1669 /// <param name="value">The <see cref="System.Object"/> | |
1670 /// that is the value of the parameter.</param> | |
1671 /// <param name="typeName">User defined type name for a table-valued parameter.</param> | |
1672 /// <returns>The <see cref="IDbDataParameter"/> object.</returns> | |
1673 public IDbDataParameter Parameter( | |
1674 ParameterDirection parameterDirection, | |
1675 string parameterName, | |
1676 object value, | |
1677 string typeName) | |
1678 { | |
1679 var parameter = _dataProvider.CreateParameterObject(Command); | |
1680 | |
1681 parameter.ParameterName = parameterName; | |
1682 parameter.Direction = parameterDirection; | |
1683 _dataProvider.SetUserDefinedType(parameter, typeName); | |
1684 _dataProvider.SetParameterValue (parameter, value); | |
1685 | |
1686 return parameter; | |
1687 } | |
1688 | |
1689 /// <summary> | |
1690 /// Adds an input parameter to the <see cref="Command"/>. | |
1691 /// </summary> | |
1692 /// <param name="parameterName">The name of the parameter.</param> | |
1693 /// <param name="value">The <see cref="System.Object"/> | |
1694 /// that is the value of the parameter.</param> | |
1695 /// <param name="dbType">One of the <seealso cref="DbType"/> values.</param> | |
1696 /// <param name="size">Size of the parameter.</param> | |
1697 /// <returns>The <see cref="IDbDataParameter"/> object.</returns> | |
1698 public IDbDataParameter Parameter( | |
1699 string parameterName, | |
1700 object value, | |
1701 DbType dbType, | |
1702 int size) | |
1703 { | |
1704 return Parameter(ParameterDirection.Input, parameterName, value, dbType, size); | |
1705 } | |
1706 | |
1707 /// <summary> | |
1708 /// Adds a parameter to the <see cref="Command"/>. | |
1709 /// </summary> | |
1710 /// <remarks> | |
1711 /// The method creates a parameter with the specified | |
1712 /// <see cref="System.Data.ParameterDirection"/> type. | |
1713 /// </remarks> | |
1714 /// <param name="parameterDirection">One of the <see cref="System.Data.ParameterDirection"/> values.</param> | |
1715 /// <param name="parameterName">The name of the parameter.</param> | |
1716 /// <param name="dbType">One of the <seealso cref="DbType"/> values.</param> | |
1717 /// <returns>The <see cref="IDbDataParameter"/> object.</returns> | |
1718 public IDbDataParameter Parameter( | |
1719 ParameterDirection parameterDirection, | |
1720 string parameterName, | |
1721 DbType dbType) | |
1722 { | |
1723 var parameter = _dataProvider.CreateParameterObject(Command); | |
1724 | |
1725 parameter.ParameterName = parameterName; | |
1726 parameter.Direction = parameterDirection; | |
1727 parameter.DbType = dbType; | |
1728 | |
1729 return parameter; | |
1730 } | |
1731 | |
1732 /// <summary> | |
1733 /// Adds a parameter to the <see cref="Command"/>. | |
1734 /// </summary> | |
1735 /// <remarks> | |
1736 /// The method creates a parameter with the specified | |
1737 /// <see cref="System.Data.ParameterDirection"/> type. | |
1738 /// </remarks> | |
1739 /// <param name="parameterDirection">One of the <see cref="System.Data.ParameterDirection"/> values.</param> | |
1740 /// <param name="parameterName">The name of the parameter.</param> | |
1741 /// <param name="dbType">One of the <seealso cref="DbType"/> values.</param> | |
1742 /// <param name="size">Size of the parameter.</param> | |
1743 /// <returns>The <see cref="IDbDataParameter"/> object.</returns> | |
1744 public IDbDataParameter Parameter( | |
1745 ParameterDirection parameterDirection, | |
1746 string parameterName, | |
1747 DbType dbType, | |
1748 int size) | |
1749 { | |
1750 var parameter = _dataProvider.CreateParameterObject(Command); | |
1751 | |
1752 parameter.ParameterName = parameterName; | |
1753 parameter.Direction = parameterDirection; | |
1754 parameter.DbType = dbType; | |
1755 parameter.Size = size; | |
1756 | |
1757 return parameter; | |
1758 } | |
1759 | |
1760 /// <summary> | |
1761 /// Creates an input parameter to the <see cref="Command"/>. | |
1762 /// </summary> | |
1763 /// <remarks> | |
1764 /// The method creates a parameter with the | |
1765 /// <see cref="System.Data.ParameterDirection">ParameterDirection.Input</see> type | |
1766 /// and <see cref="System.Data.DataRowVersion">DataRowVersion.Current</see> type. | |
1767 /// </remarks> | |
1768 /// <param name="parameterName">The name of the parameter.</param> | |
1769 /// <param name="dbType">One of the <see cref="DbType"/> values.</param> | |
1770 /// <param name="size">Size of the parameter.</param> | |
1771 /// <param name="sourceColumn">Source column for a parameter in the <see cref="DataTable"/>.</param> | |
1772 /// <returns>The <see cref="IDbDataParameter"/> object.</returns> | |
1773 public IDbDataParameter Parameter( | |
1774 string parameterName, | |
1775 DbType dbType, | |
1776 int size, | |
1777 string sourceColumn) | |
1778 { | |
1779 var param = Parameter(ParameterDirection.Input, parameterName, dbType, size); | |
1780 | |
1781 param.SourceColumn = sourceColumn; | |
1782 param.SourceVersion = DataRowVersion.Current; | |
1783 | |
1784 return param; | |
1785 } | |
1786 | |
1787 /// <summary> | |
1788 /// Creates an input parameter to the <see cref="Command"/>. | |
1789 /// </summary> | |
1790 /// <remarks> | |
1791 /// The method creates a parameter with the | |
1792 /// <see cref="System.Data.ParameterDirection">ParameterDirection.Input</see> type | |
1793 /// and <see cref="System.Data.DataRowVersion">DataRowVersion.Current</see> type. | |
1794 /// </remarks> | |
1795 /// <param name="parameterName">The name of the parameter.</param> | |
1796 /// <param name="dbType">One of the <see cref="DbType"/> values.</param> | |
1797 /// <param name="sourceColumn">Source column for a parameter in the <see cref="DataTable"/>.</param> | |
1798 /// <returns>The <see cref="IDbDataParameter"/> object.</returns> | |
1799 public IDbDataParameter Parameter( | |
1800 string parameterName, | |
1801 DbType dbType, | |
1802 string sourceColumn) | |
1803 { | |
1804 var param = Parameter(ParameterDirection.Input, parameterName, dbType); | |
1805 | |
1806 param.SourceColumn = sourceColumn; | |
1807 param.SourceVersion = DataRowVersion.Current; | |
1808 | |
1809 return param; | |
1810 } | |
1811 | |
1812 /// <summary> | |
1813 /// Creates an input parameter to the <see cref="Command"/>. | |
1814 /// </summary> | |
1815 /// <remarks> | |
1816 /// The method creates a parameter with the | |
1817 /// <see cref="System.Data.ParameterDirection">ParameterDirection.Input</see> type | |
1818 /// and <see cref="System.Data.DataRowVersion">DataRowVersion.Current</see> type. | |
1819 /// </remarks> | |
1820 /// <param name="parameterName">The name of the parameter.</param> | |
1821 /// <param name="dbType">One of the <see cref="DbType"/> values.</param> | |
1822 /// <param name="size">Size of the parameter.</param> | |
1823 /// <param name="sourceColumn">Source column for a parameter in the <see cref="DataTable"/>.</param> | |
1824 /// <param name="dataRowVersion">Version of data to use for a parameter in the <see cref="DataTable"/>.</param> | |
1825 /// <returns>The <see cref="IDbDataParameter"/> object.</returns> | |
1826 public IDbDataParameter Parameter( | |
1827 string parameterName, | |
1828 DbType dbType, | |
1829 int size, | |
1830 string sourceColumn, | |
1831 DataRowVersion dataRowVersion) | |
1832 { | |
1833 var param = Parameter(ParameterDirection.Input, parameterName, dbType, size); | |
1834 | |
1835 param.SourceColumn = sourceColumn; | |
1836 param.SourceVersion = dataRowVersion; | |
1837 | |
1838 return param; | |
1839 } | |
1840 | |
1841 /// <summary> | |
1842 /// Creates an input parameter to the <see cref="Command"/>. | |
1843 /// </summary> | |
1844 /// <remarks> | |
1845 /// The method creates a parameter with the | |
1846 /// <see cref="System.Data.ParameterDirection">ParameterDirection.Input</see> type | |
1847 /// and <see cref="System.Data.DataRowVersion">DataRowVersion.Current</see> type. | |
1848 /// </remarks> | |
1849 /// <param name="parameterName">The name of the parameter.</param> | |
1850 /// <param name="dbType">One of the <see cref="DbType"/> values.</param> | |
1851 /// <param name="sourceColumn">Source column for a parameter in the <see cref="DataTable"/>.</param> | |
1852 /// <param name="dataRowVersion">Version of data to use for a parameter in the <see cref="DataTable"/>.</param> | |
1853 /// <returns>The <see cref="IDbDataParameter"/> object.</returns> | |
1854 public IDbDataParameter Parameter( | |
1855 string parameterName, | |
1856 DbType dbType, | |
1857 string sourceColumn, | |
1858 DataRowVersion dataRowVersion) | |
1859 { | |
1860 var param = Parameter(ParameterDirection.Input, parameterName, dbType); | |
1861 | |
1862 param.SourceColumn = sourceColumn; | |
1863 param.SourceVersion = dataRowVersion; | |
1864 | |
1865 return param; | |
1866 } | |
1867 | |
1868 public ConvertType GetConvertTypeToParameter() | |
1869 { | |
1870 return Command.CommandType == CommandType.StoredProcedure ? | |
1871 ConvertType.NameToSprocParameter: | |
1872 ConvertType.NameToCommandParameter; | |
1873 } | |
1874 | |
1875 #endregion | |
1876 | |
1877 #region SetCommand | |
1878 | |
1879 /// <summary> | |
1880 /// Specifies the action that command is supposed to perform, i.e. Select, Insert, Update, Delete. | |
1881 /// It is used in Execute methods of the <see cref="DbManager"/> class to identify command instance | |
1882 /// to be used. | |
1883 /// </summary> | |
1884 enum CommandAction | |
1885 { | |
1886 Select, | |
1887 Insert, | |
1888 Update, | |
1889 Delete | |
1890 } | |
1891 | |
1892 private bool _executed; | |
1893 private bool _prepared; | |
1894 | |
1895 private IDbDataParameter[] _selectCommandParameters; | |
1896 private IDbDataParameter[] _insertCommandParameters; | |
1897 private IDbDataParameter[] _updateCommandParameters; | |
1898 private IDbDataParameter[] _deleteCommandParameters; | |
1899 | |
1900 private void SetCommand(CommandAction commandAction, IDbCommand command) | |
1901 { | |
1902 switch (commandAction) | |
1903 { | |
1904 case CommandAction.Select: _selectCommand = command; break; | |
1905 case CommandAction.Insert: _insertCommand = command; break; | |
1906 case CommandAction.Update: _updateCommand = command; break; | |
1907 case CommandAction.Delete: _deleteCommand = command; break; | |
1908 } | |
1909 } | |
1910 | |
1911 private IDbCommand GetCommand(CommandAction commandAction) | |
1912 { | |
1913 switch (commandAction) | |
1914 { | |
1915 default: | |
1916 //case CommandAction.Select: | |
1917 return SelectCommand; | |
1918 case CommandAction.Insert: return InsertCommand; | |
1919 case CommandAction.Update: return UpdateCommand; | |
1920 case CommandAction.Delete: return DeleteCommand; | |
1921 } | |
1922 } | |
1923 | |
1924 private IDbCommand GetCommand(CommandAction commandAction, CommandType commandType) | |
1925 { | |
1926 IDbCommand command; | |
1927 | |
1928 switch (commandAction) | |
1929 { | |
1930 default : command = _selectCommand; break; | |
1931 case CommandAction.Insert : command = _insertCommand; break; | |
1932 case CommandAction.Update : command = _updateCommand; break; | |
1933 case CommandAction.Delete : command = _deleteCommand; break; | |
1934 } | |
1935 | |
1936 if (command != null && !DataProvider.CanReuseCommand(command, commandType)) | |
1937 { | |
1938 command.Dispose(); | |
1939 | |
1940 switch (commandAction) | |
1941 { | |
1942 default : _selectCommand = null; break; | |
1943 case CommandAction.Insert : _insertCommand = null; break; | |
1944 case CommandAction.Update : _updateCommand = null; break; | |
1945 case CommandAction.Delete : _deleteCommand = null; break; | |
1946 } | |
1947 } | |
1948 | |
1949 return GetCommand(commandAction); | |
1950 } | |
1951 | |
1952 private void SetCommandParameters(CommandAction commandAction, IDbDataParameter[] commandParameters) | |
1953 { | |
1954 switch (commandAction) | |
1955 { | |
1956 case CommandAction.Select: _selectCommandParameters = commandParameters; break; | |
1957 case CommandAction.Insert: _insertCommandParameters = commandParameters; break; | |
1958 case CommandAction.Update: _updateCommandParameters = commandParameters; break; | |
1959 case CommandAction.Delete: _deleteCommandParameters = commandParameters; break; | |
1960 } | |
1961 } | |
1962 | |
1963 private IDbDataParameter[] GetCommandParameters(CommandAction commandAction) | |
1964 { | |
1965 switch (commandAction) | |
1966 { | |
1967 default: | |
1968 //case CommandAction.Select: | |
1969 return _selectCommandParameters; | |
1970 case CommandAction.Insert: return _insertCommandParameters; | |
1971 case CommandAction.Update: return _updateCommandParameters; | |
1972 case CommandAction.Delete: return _deleteCommandParameters; | |
1973 } | |
1974 } | |
1975 | |
1976 private DbManager SetCommand( | |
1977 CommandAction commandAction, | |
1978 CommandType commandType, | |
1979 string commandText, | |
1980 params IDbDataParameter[] commandParameters) | |
1981 { | |
1982 if (_executed) | |
1983 { | |
1984 _executed = false; | |
1985 _prepared = false; | |
1986 } | |
1987 | |
1988 PrepareCommand(commandAction, commandType, commandText, commandParameters); | |
1989 | |
1990 return this; | |
1991 } | |
1992 | |
1993 private DbManager SetSpCommand( | |
1994 CommandAction commandAction, | |
1995 string spName, | |
1996 bool openNewConnectionToDiscoverParameters, | |
1997 params object[] parameterValues) | |
1998 { | |
1999 return SetCommand( | |
2000 commandAction, | |
2001 CommandType.StoredProcedure, | |
2002 spName, | |
2003 CreateSpParameters(spName, parameterValues, openNewConnectionToDiscoverParameters)); | |
2004 } | |
2005 | |
2006 private DbManager SetSpCommand( | |
2007 CommandAction commandAction, | |
2008 string spName, | |
2009 params object[] parameterValues) | |
2010 { | |
2011 return SetCommand( | |
2012 commandAction, | |
2013 CommandType.StoredProcedure, | |
2014 spName, | |
2015 CreateSpParameters(spName, parameterValues, Configuration.OpenNewConnectionToDiscoverParameters)); | |
2016 } | |
2017 | |
2018 #region Select | |
2019 | |
2020 /// <summary> | |
2021 /// Creates a SQL statement. | |
2022 /// </summary> | |
2023 /// <param name="commandText">The command text to execute.</param> | |
2024 /// <returns>Current instance.</returns> | |
2025 public DbManager SetCommand( | |
2026 string commandText) | |
2027 { | |
2028 return SetCommand(CommandAction.Select, CommandType.Text, commandText, null); | |
2029 } | |
2030 | |
2031 /// <summary> | |
2032 /// Creates a SQL statement. | |
2033 /// </summary> | |
2034 /// <param name="commandType">The <see cref="System.Data.CommandType"/> (stored procedure, text, etc.)</param> | |
2035 /// <param name="commandText">The command text to execute.</param> | |
2036 /// <returns>Current instance.</returns> | |
2037 public DbManager SetCommand( | |
2038 CommandType commandType, | |
2039 string commandText) | |
2040 { | |
2041 return SetCommand(CommandAction.Select, commandType, commandText, null); | |
2042 } | |
2043 | |
2044 /// <summary> | |
2045 /// Creates a SQL statement. | |
2046 /// </summary> | |
2047 /// <remarks> | |
2048 /// The method can be used to create the <i>INSERT</i>, <i>UPDATE</i>, and <i>DELETE</i> SQL statements. | |
2049 /// </remarks> | |
2050 /// <param name="commandText">The command text to execute.</param> | |
2051 /// <param name="commandParameters">An array of parameters used to executes the command.</param> | |
2052 /// <returns>Current instance.</returns> | |
2053 public DbManager SetCommand( | |
2054 string commandText, | |
2055 params IDbDataParameter[] commandParameters) | |
2056 { | |
2057 return SetCommand(CommandAction.Select, CommandType.Text, commandText, commandParameters); | |
2058 } | |
2059 | |
2060 /// <summary> | |
2061 /// Creates a SQL statement. | |
2062 /// </summary> | |
2063 /// <param name="commandType">The <see cref="System.Data.CommandType"/> (stored procedure, text, etc.)</param> | |
2064 /// <param name="commandText">The command text to execute.</param> | |
2065 /// <param name="commandParameters">An array of parameters used to executes the command.</param> | |
2066 /// <returns>Current instance.</returns> | |
2067 public DbManager SetCommand( | |
2068 CommandType commandType, | |
2069 string commandText, | |
2070 params IDbDataParameter[] commandParameters) | |
2071 { | |
2072 return SetCommand(CommandAction.Select, commandType, commandText, commandParameters); | |
2073 } | |
2074 | |
2075 /// <summary> | |
2076 /// Creates a command to be executed as a stored procedure using the provided parameter values. | |
2077 /// </summary> | |
2078 /// <remarks> | |
2079 /// The method queries the database to discover the parameters for the stored procedure | |
2080 /// (the first time each stored procedure is called), | |
2081 /// and assign the values based on parameter order. | |
2082 /// </remarks> | |
2083 /// <param name="spName">The name of the stored procedure</param> | |
2084 /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param> | |
2085 /// <returns>Current instance.</returns> | |
2086 public DbManager SetSpCommand( | |
2087 string spName, | |
2088 params object[] parameterValues) | |
2089 { | |
2090 return SetSpCommand(CommandAction.Select, spName, parameterValues); | |
2091 } | |
2092 | |
2093 public DbManager SetSpCommand( | |
2094 string spName, | |
2095 bool openNewConnectionToDiscoverParameters, | |
2096 params object[] parameterValues) | |
2097 { | |
2098 return SetSpCommand(CommandAction.Select, spName, openNewConnectionToDiscoverParameters, parameterValues); | |
2099 } | |
2100 | |
2101 public DbManager SetCommand(SqlQuery sql, params IDbDataParameter[] commandParameters) | |
2102 { | |
2103 var sb = new StringBuilder(); | |
2104 | |
2105 DataProvider.CreateSqlProvider().BuildSql(0, sql, sb, 0, 0, false); | |
2106 | |
2107 var command = sb.ToString(); | |
2108 | |
2109 if (TraceSwitch.TraceInfo) | |
2110 { | |
2111 var info = string.Format("{0} {1}\n{2}", DataProvider.Name, ConfigurationString, command); | |
2112 | |
2113 if (commandParameters != null && commandParameters.Length > 0) | |
2114 foreach (var p in commandParameters) | |
2115 info += string.Format("\n{0}\t{1}", p.ParameterName, p.Value); | |
2116 | |
2117 WriteTraceLine(info, TraceSwitch.DisplayName); | |
2118 } | |
2119 | |
2120 return SetCommand(command, commandParameters); | |
2121 } | |
2122 | |
2123 #endregion | |
2124 | |
2125 #region Insert | |
2126 | |
2127 /// <summary> | |
2128 /// Creates an Insert SQL statement. | |
2129 /// </summary> | |
2130 /// <remarks> | |
2131 /// The method can be used to create the <i>INSERT</i>, <i>UPDATE</i>, and <i>DELETE</i> SQL statements. | |
2132 /// </remarks> | |
2133 /// <param name="commandText">The command text to execute.</param> | |
2134 /// <param name="commandParameters">An array of parameters used to executes the command.</param> | |
2135 /// <returns>Current instance.</returns> | |
2136 public DbManager SetInsertCommand( | |
2137 string commandText, | |
2138 params IDbDataParameter[] commandParameters) | |
2139 { | |
2140 return SetCommand( | |
2141 CommandAction.Insert, CommandType.Text, commandText, commandParameters); | |
2142 } | |
2143 | |
2144 /// <summary> | |
2145 /// Creates an Insert SQL statement. | |
2146 /// </summary> | |
2147 /// <param name="commandType">The <see cref="System.Data.CommandType"/> (stored procedure, text, etc.)</param> | |
2148 /// <param name="commandText">The command text to execute.</param> | |
2149 /// <param name="commandParameters">An array of parameters used to executes the command.</param> | |
2150 /// <returns>Current instance.</returns> | |
2151 public DbManager SetInsertCommand( | |
2152 CommandType commandType, | |
2153 string commandText, | |
2154 params IDbDataParameter[] commandParameters) | |
2155 { | |
2156 return SetCommand( | |
2157 CommandAction.Insert, commandType, commandText, commandParameters); | |
2158 } | |
2159 | |
2160 /// <summary> | |
2161 /// Creates an Insert command to be executed as a stored procedure using the provided parameter values. | |
2162 /// </summary> | |
2163 /// <remarks> | |
2164 /// The method queries the database to discover the parameters for the stored procedure | |
2165 /// (the first time each stored procedure is called), | |
2166 /// and assign the values based on parameter order. | |
2167 /// </remarks> | |
2168 /// <param name="spName">The name of the stored procedure</param> | |
2169 /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param> | |
2170 /// <returns>Current instance.</returns> | |
2171 public DbManager SetInsertSpCommand( | |
2172 string spName, | |
2173 params object[] parameterValues) | |
2174 { | |
2175 return SetSpCommand(CommandAction.Insert, spName, parameterValues); | |
2176 } | |
2177 | |
2178 #endregion | |
2179 | |
2180 #region Update | |
2181 | |
2182 /// <summary> | |
2183 /// Creates an Update SQL statement. | |
2184 /// </summary> | |
2185 /// <remarks> | |
2186 /// The method can be used to create the <i>INSERT</i>, <i>UPDATE</i>, and <i>DELETE</i> SQL statements. | |
2187 /// </remarks> | |
2188 /// <param name="commandText">The command text to execute.</param> | |
2189 /// <param name="commandParameters">An array of parameters used to executes the command.</param> | |
2190 /// <returns>Current instance.</returns> | |
2191 public DbManager SetUpdateCommand( | |
2192 string commandText, | |
2193 params IDbDataParameter[] commandParameters) | |
2194 { | |
2195 return SetCommand( | |
2196 CommandAction.Update, CommandType.Text, commandText, commandParameters); | |
2197 } | |
2198 | |
2199 /// <summary> | |
2200 /// Creates an Update SQL statement. | |
2201 /// </summary> | |
2202 /// <param name="commandType">The <see cref="System.Data.CommandType"/> (stored procedure, text, etc.)</param> | |
2203 /// <param name="commandText">The command text to execute.</param> | |
2204 /// <param name="commandParameters">An array of parameters used to executes the command.</param> | |
2205 /// <returns>Current instance.</returns> | |
2206 public DbManager SetUpdateCommand( | |
2207 CommandType commandType, | |
2208 string commandText, | |
2209 params IDbDataParameter[] commandParameters) | |
2210 { | |
2211 return SetCommand( | |
2212 CommandAction.Update, commandType, commandText, commandParameters); | |
2213 } | |
2214 | |
2215 /// <summary> | |
2216 /// Creates an Update command to be executed as a stored procedure using the provided parameter values. | |
2217 /// </summary> | |
2218 /// <remarks> | |
2219 /// The method queries the database to discover the parameters for the stored procedure | |
2220 /// (the first time each stored procedure is called), | |
2221 /// and assign the values based on parameter order. | |
2222 /// </remarks> | |
2223 /// <param name="spName">The name of the stored procedure</param> | |
2224 /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param> | |
2225 /// <returns>Current instance.</returns> | |
2226 public DbManager SetUpdateSpCommand( | |
2227 string spName, | |
2228 params object[] parameterValues) | |
2229 { | |
2230 return SetSpCommand(CommandAction.Update, spName, parameterValues); | |
2231 } | |
2232 | |
2233 #endregion | |
2234 | |
2235 #region Delete | |
2236 | |
2237 /// <summary> | |
2238 /// Creates a Delete SQL statement. | |
2239 /// </summary> | |
2240 /// <remarks> | |
2241 /// The method can be used to create the <i>INSERT</i>, <i>UPDATE</i>, and <i>DELETE</i> SQL statements. | |
2242 /// </remarks> | |
2243 /// <param name="commandText">The command text to execute.</param> | |
2244 /// <param name="commandParameters">An array of parameters used to executes the command.</param> | |
2245 /// <returns>Current instance.</returns> | |
2246 public DbManager SetDeleteCommand( | |
2247 string commandText, | |
2248 params IDbDataParameter[] commandParameters) | |
2249 { | |
2250 return SetCommand( | |
2251 CommandAction.Delete, CommandType.Text, commandText, commandParameters); | |
2252 } | |
2253 | |
2254 /// <summary> | |
2255 /// Creates a Delete SQL statement. | |
2256 /// </summary> | |
2257 /// <param name="commandType">The <see cref="System.Data.CommandType"/> (stored procedure, text, etc.)</param> | |
2258 /// <param name="commandText">The command text to execute.</param> | |
2259 /// <param name="commandParameters">An array of parameters used to executes the command.</param> | |
2260 /// <returns>Current instance.</returns> | |
2261 public DbManager SetDeleteCommand( | |
2262 CommandType commandType, | |
2263 string commandText, | |
2264 params IDbDataParameter[] commandParameters) | |
2265 { | |
2266 return SetCommand( | |
2267 CommandAction.Delete, commandType, commandText, commandParameters); | |
2268 } | |
2269 | |
2270 /// <summary> | |
2271 /// Creates a Delete command to be executed as a stored procedure using the provided parameter values. | |
2272 /// </summary> | |
2273 /// <remarks> | |
2274 /// The method queries the database to discover the parameters for the stored procedure | |
2275 /// (the first time each stored procedure is called), | |
2276 /// and assign the values based on parameter order. | |
2277 /// </remarks> | |
2278 /// <param name="spName">The name of the stored procedure</param> | |
2279 /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param> | |
2280 /// <returns>Current instance.</returns> | |
2281 public DbManager SetDeleteSpCommand( | |
2282 string spName, | |
2283 params object[] parameterValues) | |
2284 { | |
2285 return SetSpCommand(CommandAction.Delete, spName, parameterValues); | |
2286 } | |
2287 | |
2288 #endregion | |
2289 | |
2290 #endregion | |
2291 | |
2292 #region Prepare | |
2293 | |
2294 private void PrepareCommand( | |
2295 CommandAction commandAction, | |
2296 CommandType commandType, | |
2297 string commandText, | |
2298 IDbDataParameter[] commandParameters) | |
2299 { | |
2300 DataProvider.PrepareCommand(ref commandType, ref commandText, ref commandParameters); | |
2301 | |
2302 LastQuery = commandText; | |
2303 | |
2304 var command = GetCommand(commandAction, commandType, commandText); | |
2305 | |
2306 SetCommand (commandAction, command); | |
2307 SetCommandParameters(commandAction, commandParameters); | |
2308 | |
2309 if (commandParameters != null) | |
2310 { | |
2311 AttachParameters(command, commandParameters); | |
2312 } | |
2313 } | |
2314 | |
2315 /// <summary> | |
2316 /// Prepares a command for execution. | |
2317 /// </summary> | |
2318 /// <returns>Current instance.</returns> | |
2319 public DbManager Prepare() | |
2320 { | |
2321 var command = GetCommand(CommandAction.Select); | |
2322 | |
2323 if (InitParameters(CommandAction.Select) == false) | |
2324 ExecuteOperation(OperationType.PrepareCommand, command.Prepare); | |
2325 | |
2326 _prepared = true; | |
2327 | |
2328 return this; | |
2329 } | |
2330 | |
2331 bool InitParameters(CommandAction commandAction) | |
2332 { | |
2333 var prepare = false; | |
2334 | |
2335 var commandParameters = GetCommandParameters(commandAction); | |
2336 | |
2337 if (commandParameters != null) | |
2338 { | |
2339 foreach (var p in commandParameters) | |
2340 { | |
2341 if (_dataProvider.InitParameter(p)) | |
2342 continue; | |
2343 | |
2344 // It forces parameter's filed 'MetaType' to be set. | |
2345 // Same for p.Size = p.Size below. | |
2346 // | |
2347 p.DbType = p.DbType; | |
2348 | |
2349 if (p.Value is string) | |
2350 { | |
2351 var len = ((string)p.Value).Length; | |
2352 | |
2353 if (p.Size < len) | |
2354 { | |
2355 p.Size = len; | |
2356 prepare = true; | |
2357 } | |
2358 else | |
2359 p.Size = p.Size; | |
2360 } | |
2361 else if (p.Value is DBNull) | |
2362 { | |
2363 p.Size = 1; | |
2364 } | |
2365 else if (p.Value is byte[]) | |
2366 { | |
2367 var len = ((byte[])p.Value).Length; | |
2368 | |
2369 if (p.Size < len) | |
2370 { | |
2371 p.Size = len; | |
2372 prepare = true; | |
2373 } | |
2374 else | |
2375 p.Size = p.Size; | |
2376 } | |
2377 else if (p.Value is char[]) | |
2378 { | |
2379 var len = ((char[])p.Value).Length; | |
2380 | |
2381 if (p.Size < len) | |
2382 { | |
2383 p.Size = len; | |
2384 prepare = true; | |
2385 } | |
2386 else | |
2387 p.Size = p.Size; | |
2388 } | |
2389 else if (p.Value is decimal) | |
2390 { | |
2391 SqlDecimal d = (decimal)p.Value; | |
2392 | |
2393 if (p.Precision < d.Precision) | |
2394 { | |
2395 p.Precision = d.Precision; | |
2396 prepare = true; | |
2397 } | |
2398 else | |
2399 p.Precision = p.Precision; | |
2400 | |
2401 if (p.Scale < d.Scale) | |
2402 { | |
2403 p.Scale = d.Scale; | |
2404 prepare = true; | |
2405 } | |
2406 else | |
2407 p.Scale = p.Scale; | |
2408 } | |
2409 } | |
2410 | |
2411 // Re-prepare command to avoid truncation. | |
2412 // | |
2413 if (prepare) | |
2414 { | |
2415 var command = GetCommand(commandAction); | |
2416 | |
2417 AttachParameters(command, commandParameters); | |
2418 command.Prepare(); | |
2419 } | |
2420 } | |
2421 | |
2422 return prepare; | |
2423 } | |
2424 | |
2425 #endregion | |
2426 | |
2427 #region ExecuteForEach | |
2428 | |
2429 /// <summary> | |
2430 /// Executes a SQL statement for a given collection of objects and | |
2431 /// returns the number of rows affected. | |
2432 /// </summary> | |
2433 /// <remarks> | |
2434 /// The method prepares the <see cref="Command"/> object | |
2435 /// and calls the <see cref="ExecuteNonQuery()"/> method for each item of the list. | |
2436 /// </remarks> | |
2437 /// <include file="Examples1.xml" path='examples/db[@name="Execute(CommandType,string,IList)"]/*' /> | |
2438 /// <param name="collection">The list of objects used to execute the command.</param> | |
2439 /// <returns>The number of rows affected by the command.</returns> | |
2440 public int ExecuteForEach(ICollection collection) | |
2441 { | |
2442 var rowsTotal = 0; | |
2443 | |
2444 if (collection != null && collection.Count != 0) | |
2445 { | |
2446 var initParameters = true; | |
2447 | |
2448 foreach (var o in collection) | |
2449 { | |
2450 if (initParameters) | |
2451 { | |
2452 initParameters = false; | |
2453 | |
2454 var parameters = GetCommandParameters(CommandAction.Select); | |
2455 | |
2456 if (parameters == null || parameters.Length == 0) | |
2457 { | |
2458 parameters = CreateParameters(o); | |
2459 | |
2460 SetCommandParameters(CommandAction.Select, parameters); | |
2461 AttachParameters(SelectCommand, parameters); | |
2462 Prepare(); | |
2463 } | |
2464 } | |
2465 | |
2466 AssignParameterValues(o); | |
2467 rowsTotal += ExecuteNonQueryInternal(); | |
2468 MapOutputParameters(o); | |
2469 } | |
2470 } | |
2471 | |
2472 return rowsTotal; | |
2473 } | |
2474 | |
2475 /// <summary> | |
2476 /// Executes a SQL statement for a given collection of objects and | |
2477 /// returns the number of rows affected. | |
2478 /// </summary> | |
2479 /// <remarks> | |
2480 /// The method prepares the <see cref="Command"/> object | |
2481 /// and calls the <see cref="ExecuteNonQuery()"/> method for each item of the list. | |
2482 /// </remarks> | |
2483 /// <include file="Examples1.xml" path='examples/db[@name="Execute(CommandType,string,IList)"]/*' /> | |
2484 /// <param name="collection">The list of objects used to execute the command.</param> | |
2485 /// <returns>The number of rows affected by the command.</returns> | |
2486 public int ExecuteForEach<T>(ICollection<T> collection) | |
2487 { | |
2488 var rowsTotal = 0; | |
2489 | |
2490 if (collection != null && collection.Count != 0) | |
2491 { | |
2492 var initParameters = true; | |
2493 | |
2494 foreach (var o in collection) | |
2495 { | |
2496 if (initParameters) | |
2497 { | |
2498 initParameters = false; | |
2499 | |
2500 var parameters = GetCommandParameters(CommandAction.Select); | |
2501 | |
2502 if (parameters == null || parameters.Length == 0) | |
2503 { | |
2504 parameters = CreateParameters(o); | |
2505 | |
2506 SetCommandParameters(CommandAction.Select, parameters); | |
2507 AttachParameters(SelectCommand, parameters); | |
2508 Prepare(); | |
2509 } | |
2510 } | |
2511 | |
2512 AssignParameterValues(o); | |
2513 rowsTotal += ExecuteNonQueryInternal(); | |
2514 MapOutputParameters(o); | |
2515 } | |
2516 } | |
2517 | |
2518 return rowsTotal; | |
2519 } | |
2520 | |
2521 public int ExecuteForEach<T>(int maxBatchSize, IEnumerable<T> collection) | |
2522 { | |
2523 var om = _mappingSchema.GetObjectMapper(typeof(T)); | |
2524 var mms = new List<MemberMapper>(); | |
2525 | |
2526 foreach (MemberMapper mm in om) | |
2527 { | |
2528 var name = _dataProvider.Convert(mm.Name, GetConvertTypeToParameter()).ToString(); | |
2529 | |
2530 if (Command.Parameters.Contains(name)) | |
2531 mms.Add(mm); | |
2532 } | |
2533 | |
2534 return | |
2535 ExecuteForEach( | |
2536 collection, | |
2537 mms.ToArray(), | |
2538 maxBatchSize, | |
2539 obj => CreateParameters(obj)); | |
2540 } | |
2541 | |
2542 public delegate IDbDataParameter[] ParameterProvider<T>(T obj); | |
2543 | |
2544 internal int ExecuteForEach<T>(IEnumerable<T> collection, MemberMapper[] members, int maxBatchSize, ParameterProvider<T> getParameters) | |
2545 { | |
2546 if (collection == null) | |
2547 return 0; | |
2548 | |
2549 var maxRows = | |
2550 Math.Max( | |
2551 Math.Min( | |
2552 Math.Max( | |
2553 members.Length == 0? 1000 : _dataProvider.MaxParameters / members.Length, | |
2554 members.Length), | |
2555 maxBatchSize), | |
2556 1); | |
2557 var baseSql = SelectCommand.CommandText; | |
2558 var paramName = _dataProvider.Convert(".", ConvertType.NameToQueryParameter).ToString(); | |
2559 var rowsTotal = 0; | |
2560 var nRows = 0; | |
2561 var initParameters = true; | |
2562 var saveCanRaseEvent = _canRaiseEvents; | |
2563 | |
2564 _canRaiseEvents = false; | |
2565 | |
2566 var sb = new StringBuilder(); | |
2567 var rowSql = new List<int>(maxRows); | |
2568 IDbDataParameter[] baseParameters = null; | |
2569 var parameters = new List<IDbDataParameter>(); | |
2570 var hasValue = new List<bool>(); | |
2571 | |
2572 var isPrepared = false; | |
2573 | |
2574 foreach (var obj in collection) | |
2575 { | |
2576 if (initParameters) | |
2577 { | |
2578 initParameters = false; | |
2579 baseParameters = getParameters(obj); | |
2580 | |
2581 if (maxRows != 1) | |
2582 { | |
2583 var n = 0; | |
2584 | |
2585 foreach (var p in baseParameters) | |
2586 n += p.ParameterName.Length + 3 - "{0}".Length + _dataProvider.EndOfSql.Length; | |
2587 | |
2588 maxRows = Math.Max(1, Math.Min(maxRows, _dataProvider.MaxBatchSize / (baseSql.Length + n))); | |
2589 } | |
2590 | |
2591 if (maxRows != 1) | |
2592 baseSql += _dataProvider.EndOfSql; | |
2593 } | |
2594 | |
2595 if (rowSql.Count < maxRows) | |
2596 { | |
2597 // ReSharper disable AccessToModifiedClosure | |
2598 Converter<IDbDataParameter,string> c1 = p => p.ParameterName + nRows; | |
2599 // ReSharper restore AccessToModifiedClosure | |
2600 Converter<IDbDataParameter,string> c2 = p => p.ParameterName; | |
2601 | |
2602 sb | |
2603 .Append("\n") | |
2604 .AppendFormat( | |
2605 baseSql, | |
2606 Array.ConvertAll( | |
2607 baseParameters, | |
2608 baseParameters.Length > 0 && baseParameters[0].ParameterName != paramName? c1 : c2)); | |
2609 | |
2610 rowSql.Add(sb.Length); | |
2611 | |
2612 for (var i = 0; i < members.Length; i++) | |
2613 { | |
2614 var value = members[i].GetValue(obj); | |
2615 var type = members[i].MemberAccessor.Type; | |
2616 var dbType = members[i].GetDbType(); | |
2617 | |
2618 IDbDataParameter p; | |
2619 | |
2620 if ((value == null || value == DBNull.Value) && (dbType == DbType.Binary || type == typeof(byte[])) || | |
2621 type == typeof(System.Data.Linq.Binary)) | |
2622 { | |
2623 p = Parameter(baseParameters[i].ParameterName + nRows, DBNull.Value, DbType.Binary); | |
2624 } | |
2625 else | |
2626 { | |
2627 if (value != null && value.GetType().IsEnum) | |
2628 value = MappingSchema.MapEnumToValue(value, true); | |
2629 | |
2630 p = value != null | |
2631 ? Parameter(baseParameters[i].ParameterName + nRows, value) | |
2632 : Parameter(baseParameters[i].ParameterName + nRows, DBNull.Value, members[i].GetDbType()); | |
2633 } | |
2634 | |
2635 parameters.Add(p); | |
2636 hasValue.Add(value != null); | |
2637 } | |
2638 } | |
2639 else | |
2640 { | |
2641 var n = nRows * members.Length; | |
2642 | |
2643 for (var i = 0; i < members.Length; i++) | |
2644 { | |
2645 var value = members[i].GetValue(obj); | |
2646 | |
2647 if (!hasValue[n + i] && value != null) | |
2648 { | |
2649 isPrepared = false; | |
2650 | |
2651 var type = members[i].MemberAccessor.Type; | |
2652 var dbType = members[i].GetDbType(); | |
2653 | |
2654 if (value.GetType().IsEnum) | |
2655 value = MappingSchema.MapEnumToValue(value, true); | |
2656 | |
2657 IDbDataParameter p; | |
2658 if (dbType != DbType.Object) | |
2659 p = Parameter(baseParameters[i].ParameterName + nRows, value ?? DBNull.Value, dbType); | |
2660 else | |
2661 p = Parameter(baseParameters[i].ParameterName + nRows, value ?? DBNull.Value/*, dbType*/); | |
2662 | |
2663 parameters[n + i] = p; | |
2664 hasValue [n + i] = true; | |
2665 } | |
2666 else | |
2667 { | |
2668 if (value != null && value.GetType().IsEnum) | |
2669 value = MappingSchema.MapEnumToValue(value, true); | |
2670 | |
2671 _dataProvider.SetParameterValue( | |
2672 parameters[n + i], | |
2673 value ?? DBNull.Value); | |
2674 //value == null || members[i].MapMemberInfo.Nullable && _mappingSchema.IsNull(value) | |
2675 // ? DBNull.Value | |
2676 // : value); | |
2677 } | |
2678 | |
2679 } | |
2680 } | |
2681 | |
2682 nRows++; | |
2683 | |
2684 if (nRows >= maxRows) | |
2685 { | |
2686 if (!isPrepared) | |
2687 { | |
2688 SetCommand(sb.ToString(), parameters.ToArray()); | |
2689 Prepare(); | |
2690 isPrepared = true; | |
2691 } | |
2692 else | |
2693 { | |
2694 InitParameters(CommandAction.Select); | |
2695 } | |
2696 | |
2697 var n = ExecuteNonQueryInternal(); | |
2698 if (n > 0) | |
2699 rowsTotal += n; | |
2700 | |
2701 nRows = 0; | |
2702 } | |
2703 } | |
2704 | |
2705 if (nRows > 0) | |
2706 { | |
2707 if (rowSql.Count >= maxRows) | |
2708 { | |
2709 var nps = nRows * members.Length; | |
2710 parameters.RemoveRange(nps, parameters.Count - nps); | |
2711 | |
2712 sb.Length = rowSql[nRows - 1]; | |
2713 } | |
2714 | |
2715 SetCommand(sb.ToString(), parameters.ToArray()); | |
2716 Prepare(); | |
2717 | |
2718 var n = ExecuteNonQueryInternal(); | |
2719 if (n > 0) | |
2720 rowsTotal += n; | |
2721 } | |
2722 | |
2723 _canRaiseEvents = saveCanRaseEvent; | |
2724 | |
2725 return rowsTotal; | |
2726 } | |
2727 | |
2728 /// <summary> | |
2729 /// Executes a SQL statement for the <see cref="DataTable"/> and | |
2730 /// returns the number of rows affected. | |
2731 /// </summary> | |
2732 /// <remarks> | |
2733 /// The method prepares the <see cref="Command"/> object | |
2734 /// and calls the <see cref="ExecuteNonQuery()"/> method for each item | |
2735 /// of the <see cref="DataTable"/>. | |
2736 /// </remarks> | |
2737 /// <include file="Examples1.xml" path='examples/db[@name="Execute(CommandType,string,DataTable)"]/*' /> | |
2738 /// <param name="table">An instance of the <see cref="DataTable"/> class to execute the command.</param> | |
2739 /// <returns>The number of rows affected by the command.</returns> | |
2740 public int ExecuteForEach(DataTable table) | |
2741 { | |
2742 var rowsTotal = 0; | |
2743 | |
2744 if (table != null && table.Rows.Count != 0) | |
2745 { | |
2746 var parameters = GetCommandParameters(CommandAction.Select); | |
2747 | |
2748 if (parameters == null || parameters.Length == 0) | |
2749 { | |
2750 parameters = CreateParameters(table.Rows[0]); | |
2751 | |
2752 SetCommandParameters(CommandAction.Select, parameters); | |
2753 AttachParameters(SelectCommand, parameters); | |
2754 Prepare(); | |
2755 } | |
2756 | |
2757 foreach (DataRow dr in table.Rows) | |
2758 { | |
2759 AssignParameterValues(dr); | |
2760 rowsTotal += ExecuteNonQueryInternal(); | |
2761 } | |
2762 } | |
2763 | |
2764 return rowsTotal; | |
2765 } | |
2766 | |
2767 /// <summary> | |
2768 /// Executes a SQL statement for the first table of the <see cref="DataSet"/> | |
2769 /// and returns the number of rows affected. | |
2770 /// </summary> | |
2771 /// <remarks> | |
2772 /// The method prepares the <see cref="Command"/> object | |
2773 /// and calls the <see cref="ExecuteNonQuery()"/> method for each item of the first table. | |
2774 /// </remarks> | |
2775 /// <include file="Examples1.xml" path='examples/db[@name="Execute(CommandType,string,DataSet)"]/*' /> | |
2776 /// <param name="dataSet">An instance of the <see cref="DataSet"/> class to execute the command.</param> | |
2777 /// <returns>The number of rows affected by the command.</returns> | |
2778 public int ExecuteForEach(DataSet dataSet) | |
2779 { | |
2780 return ExecuteForEach(dataSet.Tables[0]); | |
2781 } | |
2782 | |
2783 /// <summary> | |
2784 /// Executes a SQL statement for the specified table of the <see cref="DataSet"/> | |
2785 /// and returns the number of rows affected. | |
2786 /// </summary> | |
2787 /// <remarks> | |
2788 /// The method prepares the <see cref="Command"/> object | |
2789 /// and calls the <see cref="ExecuteNonQuery()"/> method for each item of the first table. | |
2790 /// </remarks> | |
2791 /// <include file="Examples1.xml" path='examples/db[@name="Execute(CommandType,string,DataSet,string)"]/*' /> | |
2792 /// <param name="dataSet">An instance of the <see cref="DataSet"/> class to execute the command.</param> | |
2793 /// <param name="nameOrIndex">The table name or index. | |
2794 /// name/index.</param> | |
2795 /// <returns>The number of rows affected by the command.</returns> | |
2796 public int ExecuteForEach(DataSet dataSet, NameOrIndexParameter nameOrIndex) | |
2797 { | |
2798 return nameOrIndex.ByName ? ExecuteForEach(dataSet.Tables[nameOrIndex.Name]) | |
2799 : ExecuteForEach(dataSet.Tables[nameOrIndex.Index]); | |
2800 } | |
2801 | |
2802 #endregion | |
2803 | |
2804 #region ExecuteNonQuery | |
2805 | |
2806 /// <summary> | |
2807 /// Executes a SQL statement and returns the number of rows affected. | |
2808 /// </summary> | |
2809 /// <remarks> | |
2810 /// The method can be used to execute the <i>INSERT</i>, <i>UPDATE</i>, and <i>DELETE</i> SQL statements. | |
2811 /// </remarks> | |
2812 /// <include file="Examples1.xml" path='examples/db[@name="ExecuteNonQuery()"]/*' /> | |
2813 /// <returns>The number of rows affected by the command.</returns> | |
2814 public int ExecuteNonQuery() | |
2815 { | |
2816 if (_prepared) | |
2817 InitParameters(CommandAction.Select); | |
2818 | |
2819 return ExecuteNonQueryInternal(); | |
2820 } | |
2821 | |
2822 /// <summary> | |
2823 /// Executes a SQL statement and returns the number of rows affected. | |
2824 /// </summary> | |
2825 /// <remarks> | |
2826 /// The method can be used to execute the <i>INSERT</i>, <i>UPDATE</i>, and <i>DELETE</i> SQL statements. | |
2827 /// </remarks> | |
2828 /// <param name="returnValueMember">Name of a <see cref="MemberMapper"/> to map return value.</param> | |
2829 /// <param name="obj">An <see cref="System.Object"/> to map from command parameters.</param> | |
2830 /// <returns>The number of rows affected by the command.</returns> | |
2831 public int ExecuteNonQuery( | |
2832 string returnValueMember, | |
2833 object obj) | |
2834 { | |
2835 var rowsAffected = ExecuteNonQuery(); | |
2836 | |
2837 MapOutputParameters(returnValueMember, obj); | |
2838 | |
2839 return rowsAffected; | |
2840 } | |
2841 | |
2842 /// <summary> | |
2843 /// Executes a SQL statement and returns the number of rows affected. | |
2844 /// </summary> | |
2845 /// <remarks> | |
2846 /// The method can be used to execute the <i>INSERT</i>, <i>UPDATE</i>, and <i>DELETE</i> SQL statements. | |
2847 /// </remarks> | |
2848 /// <param name="obj">An <see cref="System.Object"/> to map from command parameters.</param> | |
2849 /// <returns>The number of rows affected by the command.</returns> | |
2850 public int ExecuteNonQuery(object obj) | |
2851 { | |
2852 var rowsAffected = ExecuteNonQuery(); | |
2853 | |
2854 MapOutputParameters(null, obj); | |
2855 | |
2856 return rowsAffected; | |
2857 } | |
2858 | |
2859 /// <summary> | |
2860 /// Executes a SQL statement and returns the number of rows affected. | |
2861 /// </summary> | |
2862 /// <remarks> | |
2863 /// The method can be used to execute the <i>INSERT</i>, <i>UPDATE</i>, and <i>DELETE</i> SQL statements. | |
2864 /// </remarks> | |
2865 /// <param name="returnValueMember">Name of a <see cref="MemberMapper"/> to map return value.</param> | |
2866 /// <param name="objects">An array of <see cref="System.Object"/> to map | |
2867 /// from command parameters.</param> | |
2868 /// <returns>The number of rows affected by the command.</returns> | |
2869 public int ExecuteNonQuery( | |
2870 string returnValueMember, | |
2871 params object[] objects) | |
2872 { | |
2873 var rowsAffected = ExecuteNonQuery(); | |
2874 | |
2875 MapOutputParameters(returnValueMember, objects); | |
2876 | |
2877 return rowsAffected; | |
2878 } | |
2879 | |
2880 /// <summary> | |
2881 /// Executes a SQL statement and returns the number of rows affected. | |
2882 /// </summary> | |
2883 /// <remarks> | |
2884 /// The method can be used to execute the <i>INSERT</i>, <i>UPDATE</i>, and <i>DELETE</i> SQL statements. | |
2885 /// </remarks> | |
2886 /// <param name="objects">An array of <see cref="System.Object"/> to map | |
2887 /// from command parameters.</param> | |
2888 /// <returns>The number of rows affected by the command.</returns> | |
2889 public int ExecuteNonQuery(params object[] objects) | |
2890 { | |
2891 var rowsAffected = ExecuteNonQuery(); | |
2892 | |
2893 MapOutputParameters(null, objects); | |
2894 | |
2895 return rowsAffected; | |
2896 } | |
2897 | |
2898 /// <summary> | |
2899 /// Executes several SQL statements at a time using single roundtrip to the server (if supported by data provider). | |
2900 /// </summary> | |
2901 /// <remarks> | |
2902 /// All parameters of the query must be arrays of type corresponding to the type of the parameter. | |
2903 /// The value of the <paramref name="iterations"/> parameter must be equal to the number of elements of each array. | |
2904 /// </remarks> | |
2905 /// <param name="iterations">The number of iterations.</param> | |
2906 /// <returns>The number of rows affected by the command.</returns> | |
2907 public int ExecuteArray(int iterations) | |
2908 { | |
2909 return ExecuteOperation<int>(OperationType.ExecuteNonQuery, () => DataProvider.ExecuteArray(SelectCommand, iterations)); | |
2910 } | |
2911 | |
2912 #endregion | |
2913 | |
2914 #region ExecuteScalar | |
2915 | |
2916 /// <summary> | |
2917 /// Executes the query, and returns the first column of the first row | |
2918 /// in the resultset returned by the query. Extra columns or rows are | |
2919 /// ignored. | |
2920 /// </summary> | |
2921 /// <returns>The first column of the first row in the resultset.</returns> | |
2922 /// <seealso cref="ExecuteScalar(ScalarSourceType, NameOrIndexParameter)"/> | |
2923 public object ExecuteScalar() | |
2924 { | |
2925 if (_prepared) | |
2926 InitParameters(CommandAction.Select); | |
2927 | |
2928 using (var rd = ExecuteReaderInternal(CommandBehavior.Default)) | |
2929 return rd.Read() && rd.FieldCount > 0 ? rd.GetValue(0) : null; | |
2930 } | |
2931 | |
2932 /// <summary> | |
2933 /// Executes the query, and returns the value with specified scalar | |
2934 /// source type. | |
2935 /// </summary> | |
2936 /// <param name="sourceType">The method used to return the scalar | |
2937 /// value.</param> | |
2938 /// <returns><list type="table"> | |
2939 /// <listheader> | |
2940 /// <term>ScalarSourceType</term> | |
2941 /// <description>Return value</description> | |
2942 /// </listheader> | |
2943 /// <item> | |
2944 /// <term>DataReader</term> | |
2945 /// <description>The first column of the first row in the resultset. | |
2946 /// </description> | |
2947 /// </item> | |
2948 /// <item> | |
2949 /// <term>OutputParameter</term> | |
2950 /// <description>The value of the first output or input/output | |
2951 /// parameter returned.</description> | |
2952 /// </item> | |
2953 /// <item> | |
2954 /// <term>ReturnValue</term> | |
2955 /// <description>The value of the "return value" parameter returned. | |
2956 /// </description> | |
2957 /// </item> | |
2958 /// <item> | |
2959 /// <term>AffectedRows</term> | |
2960 /// <description>The number of rows affected.</description> | |
2961 /// </item> | |
2962 /// </list> | |
2963 /// </returns> | |
2964 /// <seealso cref="ExecuteScalar(ScalarSourceType, NameOrIndexParameter)"/> | |
2965 public object ExecuteScalar(ScalarSourceType sourceType) | |
2966 { | |
2967 return ExecuteScalar(sourceType, new NameOrIndexParameter()); | |
2968 } | |
2969 | |
2970 /// <summary> | |
2971 /// Executes the query, and returns the value with specified scalar | |
2972 /// source type. | |
2973 /// </summary> | |
2974 /// <param name="sourceType">The method used to return the scalar value.</param> | |
2975 /// <param name="nameOrIndex">The column name/index or output parameter name/index.</param> | |
2976 /// <returns><list type="table"> | |
2977 /// <listheader> | |
2978 /// <term>ScalarSourceType</term> | |
2979 /// <description>Return value</description> | |
2980 /// </listheader> | |
2981 /// <item> | |
2982 /// <term>DataReader</term> | |
2983 /// <description>The column with specified name or at specified index | |
2984 /// of the first row in the resultset.</description> | |
2985 /// </item> | |
2986 /// <item> | |
2987 /// <term>OutputParameter</term> | |
2988 /// <description>The value of the output or input/output parameter | |
2989 /// returned with specified name or at specified index.</description> | |
2990 /// </item> | |
2991 /// <item> | |
2992 /// <term>ReturnValue</term> | |
2993 /// <description>The value of the "return value" parameter returned. | |
2994 /// The index parameter is ignored.</description> | |
2995 /// </item> | |
2996 /// <item> | |
2997 /// <term>AffectedRows</term> | |
2998 /// <description>The number of rows affected. The index parameter is | |
2999 /// ignored.</description> | |
3000 /// </item> | |
3001 /// </list> | |
3002 /// </returns> | |
3003 public object ExecuteScalar(ScalarSourceType sourceType, NameOrIndexParameter nameOrIndex) | |
3004 { | |
3005 if (_prepared) | |
3006 InitParameters(CommandAction.Select); | |
3007 | |
3008 switch (sourceType) | |
3009 { | |
3010 case ScalarSourceType.DataReader: | |
3011 using (var reader = ExecuteReaderInternal()) | |
3012 if (reader.Read()) | |
3013 return reader.GetValue(nameOrIndex.ByName ? reader.GetOrdinal(nameOrIndex.Name) : nameOrIndex.Index); | |
3014 | |
3015 break; | |
3016 | |
3017 case ScalarSourceType.OutputParameter: | |
3018 ExecuteNonQueryInternal(); | |
3019 | |
3020 if (nameOrIndex.ByName) | |
3021 { | |
3022 var name = (string)_dataProvider.Convert(nameOrIndex.Name, GetConvertTypeToParameter()); | |
3023 return Parameter(name).Value; | |
3024 } | |
3025 | |
3026 var index = nameOrIndex.Index; | |
3027 foreach (IDataParameter p in SelectCommand.Parameters) | |
3028 { | |
3029 // Skip the return value parameter. | |
3030 // | |
3031 if (p.Direction == ParameterDirection.ReturnValue) | |
3032 continue; | |
3033 | |
3034 if (0 == index) | |
3035 return p.Value; | |
3036 | |
3037 --index; | |
3038 } | |
3039 break; | |
3040 | |
3041 case ScalarSourceType.ReturnValue: | |
3042 ExecuteNonQueryInternal(); | |
3043 | |
3044 foreach (IDataParameter p in SelectCommand.Parameters) | |
3045 if (p.Direction == ParameterDirection.ReturnValue) | |
3046 return p.Value; | |
3047 | |
3048 break; | |
3049 | |
3050 case ScalarSourceType.AffectedRows: | |
3051 return ExecuteNonQueryInternal(); | |
3052 | |
3053 default: | |
3054 throw new InvalidEnumArgumentException("sourceType", | |
3055 (int)sourceType, typeof(ScalarSourceType)); | |
3056 } | |
3057 | |
3058 return null; | |
3059 } | |
3060 | |
3061 /// <summary> | |
3062 /// Executes the query, and returns the first column of the first row | |
3063 /// in the resultset returned by the query. Extra columns or rows are | |
3064 /// ignored. | |
3065 /// </summary> | |
3066 /// <returns> | |
3067 /// The first column of the first row in the resultset.</returns> | |
3068 /// <seealso cref="ExecuteScalar{T}(ScalarSourceType, NameOrIndexParameter)"/> | |
3069 public T ExecuteScalar<T>() | |
3070 { | |
3071 var value = _mappingSchema.ConvertChangeType(ExecuteScalar(), typeof(T)); | |
3072 return value == null && typeof(T).IsEnum ? default(T) : (T)value; | |
3073 } | |
3074 | |
3075 /// <summary> | |
3076 /// Executes the query, and returns the value with specified scalar | |
3077 /// source type. | |
3078 /// </summary> | |
3079 /// <param name="sourceType">The method used to return the scalar | |
3080 /// value.</param> | |
3081 /// <returns><list type="table"> | |
3082 /// <listheader> | |
3083 /// <term>ScalarSourceType</term> | |
3084 /// <description>Return value</description> | |
3085 /// </listheader> | |
3086 /// <item> | |
3087 /// <term>DataReader</term> | |
3088 /// <description>The first column of the first row in the resultset. | |
3089 /// </description> | |
3090 /// </item> | |
3091 /// <item> | |
3092 /// <term>OutputParameter</term> | |
3093 /// <description>The value of the first output or input/output | |
3094 /// parameter returned.</description> | |
3095 /// </item> | |
3096 /// <item> | |
3097 /// <term>ReturnValue</term> | |
3098 /// <description>The value of the "return value" parameter returned. | |
3099 /// </description> | |
3100 /// </item> | |
3101 /// <item> | |
3102 /// <term>AffectedRows</term> | |
3103 /// <description>The number of rows affected.</description> | |
3104 /// </item> | |
3105 /// </list> | |
3106 /// </returns> | |
3107 /// <seealso cref="ExecuteScalar{T}(ScalarSourceType, NameOrIndexParameter)"/> | |
3108 public T ExecuteScalar<T>(ScalarSourceType sourceType) | |
3109 { | |
3110 return ExecuteScalar<T>(sourceType, new NameOrIndexParameter()); | |
3111 } | |
3112 | |
3113 /// <summary> | |
3114 /// Executes the query, and returns the value with specified scalar | |
3115 /// source type. | |
3116 /// </summary> | |
3117 /// <param name="sourceType">The method used to return the scalar value.</param> | |
3118 /// <param name="nameOrIndex">The column name/index or output parameter name/index.</param> | |
3119 /// <returns><list type="table"> | |
3120 /// <listheader> | |
3121 /// <term>ScalarSourceType</term> | |
3122 /// <description>Return value</description> | |
3123 /// </listheader> | |
3124 /// <item> | |
3125 /// <term>DataReader</term> | |
3126 /// <description>The column with specified name or at specified index | |
3127 /// of the first row in the resultset.</description> | |
3128 /// </item> | |
3129 /// <item> | |
3130 /// <term>OutputParameter</term> | |
3131 /// <description>The value of the output or input/output parameter | |
3132 /// returned with specified name or at specified index.</description> | |
3133 /// </item> | |
3134 /// <item> | |
3135 /// <term>ReturnValue</term> | |
3136 /// <description>The value of the "return value" parameter returned. | |
3137 /// The index parameter is ignored.</description> | |
3138 /// </item> | |
3139 /// <item> | |
3140 /// <term>AffectedRows</term> | |
3141 /// <description>The number of rows affected. The index parameter is | |
3142 /// ignored.</description> | |
3143 /// </item> | |
3144 /// </list> | |
3145 /// </returns> | |
3146 public T ExecuteScalar<T>(ScalarSourceType sourceType, NameOrIndexParameter nameOrIndex) | |
3147 { | |
3148 return (T)_mappingSchema.ConvertChangeType(ExecuteScalar(sourceType, nameOrIndex), typeof(T)); | |
3149 } | |
3150 | |
3151 #endregion | |
3152 | |
3153 #region ExecuteScalarList | |
3154 | |
3155 /// <summary> | |
3156 /// Executes the query, and returns the array list of values of the | |
3157 /// specified column of the every row in the resultset returned by the | |
3158 /// query. Other columns are ignored. | |
3159 /// </summary> | |
3160 /// <param name="list">The array to fill in.</param> | |
3161 /// <param name="nameOrIndex">The column name/index or output parameter name/index.</param> | |
3162 /// <param name="type">The type of the each element.</param> | |
3163 /// <returns>Array list of values of the specified column of the every | |
3164 /// row in the resultset.</returns> | |
3165 public IList ExecuteScalarList( | |
3166 IList list, | |
3167 Type type, | |
3168 NameOrIndexParameter nameOrIndex) | |
3169 { | |
3170 if (list == null) | |
3171 list = new ArrayList(); | |
3172 | |
3173 if (_prepared) | |
3174 InitParameters(CommandAction.Select); | |
3175 | |
3176 using (var dr = ExecuteReaderInternal()) | |
3177 return _mappingSchema.MapDataReaderToScalarList(dr, nameOrIndex, list, type); | |
3178 } | |
3179 | |
3180 /// <summary> | |
3181 /// Executes the query, and returns the array list of values of first | |
3182 /// column of the every row in the resultset returned by the query. | |
3183 /// Other columns are ignored. | |
3184 /// </summary> | |
3185 /// <param name="list">The array to fill in.</param> | |
3186 /// <param name="type">The type of the each element.</param> | |
3187 /// <returns>Array list of values of first column of the every row in | |
3188 /// the resultset.</returns> | |
3189 public IList ExecuteScalarList(IList list, Type type) | |
3190 { | |
3191 if (list == null) | |
3192 list = new ArrayList(); | |
3193 | |
3194 return ExecuteScalarList(list, type, 0); | |
3195 } | |
3196 | |
3197 /// <summary> | |
3198 /// Executes the query, and returns the array list of values of the | |
3199 /// specified column of the every row in the resultset returned by the | |
3200 /// query. Other columns are ignored. | |
3201 /// </summary> | |
3202 /// <param name="nameOrIndex">The column name/index.</param> | |
3203 /// <param name="type">The type of the each element.</param> | |
3204 /// <returns>Array list of values of the specified column of the every | |
3205 /// row in the resultset.</returns> | |
3206 public ArrayList ExecuteScalarList(Type type, NameOrIndexParameter nameOrIndex) | |
3207 { | |
3208 var list = new ArrayList(); | |
3209 | |
3210 ExecuteScalarList(list, type, nameOrIndex); | |
3211 | |
3212 return list; | |
3213 } | |
3214 | |
3215 /// <summary> | |
3216 /// Executes the query, and returns the array list of values of first | |
3217 /// column of the every row in the resultset returned by the query. | |
3218 /// Other columns are ignored. | |
3219 /// </summary> | |
3220 /// <param name="type">The type of the each element.</param> | |
3221 /// <returns>Array list of values of first column of the every row in | |
3222 /// the resultset.</returns> | |
3223 public ArrayList ExecuteScalarList(Type type) | |
3224 { | |
3225 var list = new ArrayList(); | |
3226 | |
3227 ExecuteScalarList(list, type, 0); | |
3228 | |
3229 return list; | |
3230 } | |
3231 | |
3232 /// <summary> | |
3233 /// Executes the query, and returns the array list of values of the | |
3234 /// specified column of the every row in the resultset returned by the | |
3235 /// query. Other columns are ignored. | |
3236 /// </summary> | |
3237 /// <param name="list">The array to fill in.</param> | |
3238 /// <param name="nameOrIndex">The column name/index or output parameter | |
3239 /// name/index.</param> | |
3240 /// <typeparam name="T">The type of the each element.</typeparam> | |
3241 /// <returns>Array list of values of the specified column of the every | |
3242 /// row in the resultset.</returns> | |
3243 public IList<T> ExecuteScalarList<T>( | |
3244 IList<T> list, | |
3245 NameOrIndexParameter nameOrIndex) | |
3246 { | |
3247 if (list == null) | |
3248 list = new List<T>(); | |
3249 | |
3250 if (_prepared) | |
3251 InitParameters(CommandAction.Select); | |
3252 | |
3253 using (var dr = ExecuteReaderInternal()) | |
3254 return _mappingSchema.MapDataReaderToScalarList(dr, nameOrIndex, list); | |
3255 } | |
3256 | |
3257 /// <summary> | |
3258 /// Executes the query, and returns the array list of values of first | |
3259 /// column of the every row in the resultset returned by the query. | |
3260 /// Other columns are ignored. | |
3261 /// </summary> | |
3262 /// <param name="list">The array to fill in.</param> | |
3263 /// <typeparam name="T">The type of the each element.</typeparam> | |
3264 /// <returns>Array list of values of first column of the every row in | |
3265 /// the resultset.</returns> | |
3266 public IList<T> ExecuteScalarList<T>(IList<T> list) | |
3267 { | |
3268 return ExecuteScalarList(list, 0); | |
3269 } | |
3270 | |
3271 /// <summary> | |
3272 /// Executes the query, and returns the array list of values of the | |
3273 /// specified column of the every row in the resultset returned by the | |
3274 /// query. Other columns are ignored. | |
3275 /// </summary> | |
3276 /// <param name="nameOrIndex">The column name/index or output parameter name/index.</param> | |
3277 /// <typeparam name="T">The type of the each element.</typeparam> | |
3278 /// <returns>Array list of values of the specified column of the every | |
3279 /// row in the resultset.</returns> | |
3280 public List<T> ExecuteScalarList<T>(NameOrIndexParameter nameOrIndex) | |
3281 { | |
3282 var list = new List<T>(); | |
3283 | |
3284 ExecuteScalarList(list, nameOrIndex); | |
3285 | |
3286 return list; | |
3287 } | |
3288 | |
3289 /// <summary> | |
3290 /// Executes the query, and returns the list of values of first | |
3291 /// column of the every row in the resultset returned by the query. | |
3292 /// Other columns are ignored. | |
3293 /// </summary> | |
3294 /// <typeparam name="T">The type of the each element.</typeparam> | |
3295 /// <returns>Array list of values of first column of the every row in | |
3296 /// the resultset.</returns> | |
3297 public List<T> ExecuteScalarList<T>() | |
3298 { | |
3299 var list = new List<T>(); | |
3300 | |
3301 ExecuteScalarList(list, 0); | |
3302 | |
3303 return list; | |
3304 } | |
3305 | |
3306 #endregion | |
3307 | |
3308 #region ExecuteScalarDictionary | |
3309 | |
3310 ///<summary> | |
3311 /// Executes the query, and returns the dictionary. | |
3312 /// The keys are loaded from a column specified by <paramref name="keyField"/> and | |
3313 /// values are loaded from a column specified by <paramref name="valueField"/>. | |
3314 /// Other columns are ignored. | |
3315 ///</summary> | |
3316 ///<param name="dic">The dictionary to add values.</param> | |
3317 ///<param name="keyField">The column name/index to load keys.</param> | |
3318 ///<param name="keyFieldType">The key type.</param> | |
3319 ///<param name="valueField">The column name/index to load values.</param> | |
3320 ///<param name="valueFieldType">The value type.</param> | |
3321 ///<returns>The loaded dictionary.</returns> | |
3322 public IDictionary ExecuteScalarDictionary( | |
3323 IDictionary dic, | |
3324 NameOrIndexParameter keyField, Type keyFieldType, | |
3325 NameOrIndexParameter valueField, Type valueFieldType) | |
3326 { | |
3327 if (dic == null) | |
3328 dic = new Hashtable(); | |
3329 | |
3330 if (_prepared) | |
3331 InitParameters(CommandAction.Select); | |
3332 | |
3333 //object nullValue = _mappingSchema.GetNullValue(type); | |
3334 | |
3335 if (keyField.ByName && keyField.Name.Length > 0 && keyField.Name[0] == '@') | |
3336 keyField = keyField.Name.Substring(1); | |
3337 | |
3338 using (var dr = ExecuteReaderInternal()) | |
3339 { | |
3340 if (dr.Read()) | |
3341 { | |
3342 var keyIndex = keyField.ByName ? dr.GetOrdinal(keyField.Name) : keyField.Index; | |
3343 var valueIndex = valueField.ByName ? dr.GetOrdinal(valueField.Name) : valueField.Index; | |
3344 | |
3345 do | |
3346 { | |
3347 var value = dr[valueIndex]; | |
3348 var key = dr[keyIndex]; | |
3349 | |
3350 if (key == null || key.GetType() != keyFieldType) | |
3351 key = key is DBNull ? null : _mappingSchema.ConvertChangeType(key, keyFieldType); | |
3352 | |
3353 if (value == null || value.GetType() != valueFieldType) | |
3354 value = value is DBNull ? null : _mappingSchema.ConvertChangeType(value, valueFieldType); | |
3355 | |
3356 dic.Add(key, value); | |
3357 } | |
3358 while (dr.Read()); | |
3359 } | |
3360 } | |
3361 | |
3362 return dic; | |
3363 } | |
3364 | |
3365 ///<summary> | |
3366 /// Executes the query, and returns the dictionary. | |
3367 /// The keys are loaded from a column specified by <paramref name="keyField"/> and | |
3368 /// values are loaded from a column specified by <paramref name="valueField"/>. | |
3369 /// Other columns are ignored. | |
3370 ///</summary> | |
3371 ///<param name="keyField">The column name/index to load keys.</param> | |
3372 ///<param name="keyFieldType">The key type.</param> | |
3373 ///<param name="valueField">The column name/index to load values.</param> | |
3374 ///<param name="valueFieldType">The value type.</param> | |
3375 ///<returns>The loaded dictionary.</returns> | |
3376 public Hashtable ExecuteScalarDictionary( | |
3377 NameOrIndexParameter keyField, Type keyFieldType, | |
3378 NameOrIndexParameter valueField, Type valueFieldType) | |
3379 { | |
3380 var table = new Hashtable(); | |
3381 | |
3382 ExecuteScalarDictionary(table, keyField, keyFieldType, valueField, valueFieldType); | |
3383 | |
3384 return table; | |
3385 } | |
3386 | |
3387 ///<summary> | |
3388 /// Executes the query, and returns the dictionary. | |
3389 /// The keys are loaded from a column specified by <paramref name="keyField"/> and | |
3390 /// values are loaded from a column specified by <paramref name="valueField"/>. | |
3391 /// Other columns are ignored. | |
3392 ///</summary> | |
3393 ///<typeparam name="TKey">The key type.</typeparam> | |
3394 ///<typeparam name="T">The value type.</typeparam> | |
3395 ///<param name="dic">The dictionary to add values.</param> | |
3396 ///<param name="keyField">The column name/index to load keys.</param> | |
3397 ///<param name="valueField">The column name/index to load values.</param> | |
3398 ///<returns>The loaded dictionary.</returns> | |
3399 public IDictionary<TKey,T> ExecuteScalarDictionary<TKey,T>( | |
3400 IDictionary<TKey,T> dic, | |
3401 NameOrIndexParameter keyField, | |
3402 NameOrIndexParameter valueField) | |
3403 { | |
3404 if (dic == null) | |
3405 dic = new Dictionary<TKey,T>(); | |
3406 | |
3407 if (_prepared) | |
3408 InitParameters(CommandAction.Select); | |
3409 | |
3410 //object nullValue = _mappingSchema.GetNullValue(type); | |
3411 | |
3412 var keyFieldType = typeof(TKey); | |
3413 var valueFieldType = typeof(T); | |
3414 | |
3415 using (var dr = ExecuteReaderInternal()) | |
3416 if (dr.Read()) | |
3417 { | |
3418 var keyIndex = keyField.ByName ? dr.GetOrdinal(keyField.Name) : keyField.Index; | |
3419 var valueIndex = valueField.ByName ? dr.GetOrdinal(valueField.Name) : valueField.Index; | |
3420 | |
3421 do | |
3422 { | |
3423 var value = dr[valueIndex]; | |
3424 var key = dr[keyIndex]; | |
3425 | |
3426 if (key == null || key.GetType() != keyFieldType) | |
3427 key = key is DBNull ? null : _mappingSchema.ConvertChangeType(key, keyFieldType); | |
3428 | |
3429 if (value == null || value.GetType() != valueFieldType) | |
3430 value = value is DBNull ? null : _mappingSchema.ConvertChangeType(value, valueFieldType); | |
3431 | |
3432 dic.Add((TKey) key, (T) value); | |
3433 } while (dr.Read()); | |
3434 } | |
3435 | |
3436 return dic; | |
3437 } | |
3438 | |
3439 ///<summary> | |
3440 /// Executes the query, and returns the dictionary. | |
3441 /// The keys are loaded from a column specified by <paramref name="keyField"/> and | |
3442 /// values are loaded from a column specified by <paramref name="valueField"/>. | |
3443 /// Other columns are ignored. | |
3444 ///</summary> | |
3445 ///<typeparam name="TKey">The key type.</typeparam> | |
3446 ///<typeparam name="T">The value type.</typeparam> | |
3447 ///<param name="keyField">The column name/index to load keys.</param> | |
3448 ///<param name="valueField">The column name/index to load values.</param> | |
3449 ///<returns>The loaded dictionary.</returns> | |
3450 public Dictionary<TKey,T> ExecuteScalarDictionary<TKey,T>( | |
3451 NameOrIndexParameter keyField, | |
3452 NameOrIndexParameter valueField) | |
3453 { | |
3454 var dic = new Dictionary<TKey,T>(); | |
3455 | |
3456 ExecuteScalarDictionary(dic, keyField, valueField); | |
3457 | |
3458 return dic; | |
3459 } | |
3460 | |
3461 #endregion | |
3462 | |
3463 #region ExecuteScalarDictionary (Index) | |
3464 | |
3465 ///<summary> | |
3466 /// Executes the query, and returns the dictionary. | |
3467 /// The keys are loaded from columns specified by <paramref name="index"/> and | |
3468 /// values are loaded from a column specified by <paramref name="valueField"/>. | |
3469 /// Other columns are ignored. | |
3470 ///</summary> | |
3471 ///<param name="dic">The dictionary to add values.</param> | |
3472 ///<param name="index">The <see cref="MapIndex"/> of the key columns.</param> | |
3473 ///<param name="valueField">The column name/index to load values.</param> | |
3474 ///<param name="valueFieldType">The value type.</param> | |
3475 ///<returns>The loaded dictionary.</returns> | |
3476 public IDictionary ExecuteScalarDictionary( | |
3477 IDictionary dic, | |
3478 MapIndex index, | |
3479 NameOrIndexParameter valueField, | |
3480 Type valueFieldType) | |
3481 { | |
3482 if (dic == null) | |
3483 dic = new Hashtable(); | |
3484 | |
3485 if (_prepared) | |
3486 InitParameters(CommandAction.Select); | |
3487 | |
3488 //object nullValue = _mappingSchema.GetNullValue(type); | |
3489 | |
3490 using (var dr = ExecuteReaderInternal()) | |
3491 if (dr.Read()) | |
3492 { | |
3493 var valueIndex = valueField.ByName ? dr.GetOrdinal(valueField.Name) : valueField.Index; | |
3494 var keyIndex = new int[index.Fields.Length]; | |
3495 | |
3496 for (var i = 0; i < keyIndex.Length; i++) | |
3497 keyIndex[i] = | |
3498 index.Fields[i].ByName | |
3499 ? dr.GetOrdinal(index.Fields[i].Name) | |
3500 : index.Fields[i].Index; | |
3501 | |
3502 do | |
3503 { | |
3504 var value = dr[valueIndex]; | |
3505 | |
3506 if (value == null || value.GetType() != valueFieldType) | |
3507 value = value is DBNull ? null : _mappingSchema.ConvertChangeType(value, valueFieldType); | |
3508 | |
3509 var key = new object[keyIndex.Length]; | |
3510 | |
3511 for (var i = 0; i < keyIndex.Length; i++) | |
3512 key[i] = dr[keyIndex[i]]; | |
3513 | |
3514 dic.Add(new CompoundValue(key), value); | |
3515 } while (dr.Read()); | |
3516 } | |
3517 | |
3518 return dic; | |
3519 } | |
3520 | |
3521 ///<summary> | |
3522 /// Executes the query, and returns the dictionary. | |
3523 /// The keys are loaded from columns specified by <paramref name="index"/> and | |
3524 /// values are loaded from a column specified by <paramref name="valueField"/>. | |
3525 /// Other columns are ignored. | |
3526 ///</summary> | |
3527 ///<param name="index">The <see cref="MapIndex"/> of the key columns.</param> | |
3528 ///<param name="valueField">The column name/index to load values.</param> | |
3529 ///<param name="valueFieldType">The value type.</param> | |
3530 ///<returns>The loaded dictionary.</returns> | |
3531 public Hashtable ExecuteScalarDictionary( | |
3532 MapIndex index, NameOrIndexParameter valueField, Type valueFieldType) | |
3533 { | |
3534 var table = new Hashtable(); | |
3535 | |
3536 ExecuteScalarDictionary(table, index, valueField, valueFieldType); | |
3537 | |
3538 return table; | |
3539 } | |
3540 | |
3541 ///<summary> | |
3542 /// Executes the query, and returns the dictionary. | |
3543 /// The keys are loaded from columns specified by <paramref name="index"/> and | |
3544 /// values are loaded from a column specified by <paramref name="valueField"/>. | |
3545 /// Other columns are ignored. | |
3546 ///</summary> | |
3547 ///<typeparam name="T">The value type.</typeparam> | |
3548 ///<param name="dic">The dictionary to add values.</param> | |
3549 ///<param name="index">The <see cref="MapIndex"/> of the key columns.</param> | |
3550 ///<param name="valueField">The column name/index to load values.</param> | |
3551 ///<returns>The loaded dictionary.</returns> | |
3552 public IDictionary<CompoundValue,T> ExecuteScalarDictionary<T>( | |
3553 IDictionary<CompoundValue, T> dic, MapIndex index, NameOrIndexParameter valueField) | |
3554 { | |
3555 if (dic == null) | |
3556 dic = new Dictionary<CompoundValue, T>(); | |
3557 | |
3558 if (_prepared) | |
3559 InitParameters(CommandAction.Select); | |
3560 | |
3561 //object nullValue = _mappingSchema.GetNullValue(type); | |
3562 | |
3563 var valueFieldType = typeof(T); | |
3564 | |
3565 using (var dr = ExecuteReaderInternal()) | |
3566 if (dr.Read()) | |
3567 { | |
3568 var valueIndex = valueField.ByName ? dr.GetOrdinal(valueField.Name) : valueField.Index; | |
3569 var keyIndex = new int[index.Fields.Length]; | |
3570 | |
3571 for (var i = 0; i < keyIndex.Length; i++) | |
3572 keyIndex[i] = index.Fields[i].ByName | |
3573 ? dr.GetOrdinal(index.Fields[i].Name) | |
3574 : index.Fields[i].Index; | |
3575 | |
3576 do | |
3577 { | |
3578 var value = dr[valueIndex]; | |
3579 | |
3580 if (value == null || value.GetType() != valueFieldType) | |
3581 value = value is DBNull ? null : _mappingSchema.ConvertChangeType(value, valueFieldType); | |
3582 | |
3583 var key = new object[keyIndex.Length]; | |
3584 | |
3585 for (var i = 0; i < keyIndex.Length; i++) | |
3586 key[i] = dr[keyIndex[i]]; | |
3587 | |
3588 dic.Add(new CompoundValue(key), (T) value); | |
3589 } while (dr.Read()); | |
3590 } | |
3591 | |
3592 return dic; | |
3593 } | |
3594 | |
3595 ///<summary> | |
3596 /// Executes the query, and returns the dictionary. | |
3597 /// The keys are loaded from columns specified by <paramref name="index"/> and | |
3598 /// values are loaded from a column specified by <paramref name="valueField"/>. | |
3599 /// Other columns are ignored. | |
3600 ///</summary> | |
3601 ///<typeparam name="T">The value type.</typeparam> | |
3602 ///<param name="index">The <see cref="MapIndex"/> of the key columns.</param> | |
3603 ///<param name="valueField">The column name/index to load values.</param> | |
3604 ///<returns>The loaded dictionary.</returns> | |
3605 public Dictionary<CompoundValue,T> ExecuteScalarDictionary<T>( | |
3606 MapIndex index, NameOrIndexParameter valueField) | |
3607 { | |
3608 var dic = new Dictionary<CompoundValue,T>(); | |
3609 | |
3610 ExecuteScalarDictionary(dic, index, valueField); | |
3611 | |
3612 return dic; | |
3613 } | |
3614 | |
3615 #endregion | |
3616 | |
3617 #region ExecuteReader | |
3618 | |
3619 /// <summary> | |
3620 /// Executes the command and builds an <see cref="IDataReader"/>. | |
3621 /// </summary> | |
3622 /// <returns>An instance of the <see cref="IDataReader"/> class.</returns> | |
3623 public IDataReader ExecuteReader() | |
3624 { | |
3625 if (_prepared) | |
3626 InitParameters(CommandAction.Select); | |
3627 | |
3628 return ExecuteReaderInternal(); | |
3629 } | |
3630 | |
3631 /// <summary> | |
3632 /// Executes the command and builds an <see cref="IDataReader"/>. | |
3633 /// </summary> | |
3634 /// <param name="commandBehavior">One of the <see cref="CommandBehavior"/> values.</param> | |
3635 /// <returns>An instance of the <see cref="IDataReader"/> class.</returns> | |
3636 public IDataReader ExecuteReader(CommandBehavior commandBehavior) | |
3637 { | |
3638 if (_prepared) | |
3639 InitParameters(CommandAction.Select); | |
3640 | |
3641 return ExecuteReaderInternal(commandBehavior); | |
3642 } | |
3643 | |
3644 #endregion | |
3645 | |
3646 #region ExecuteDataSet | |
3647 | |
3648 /// <summary> | |
3649 /// Executes a SQL statement using the provided parameters. | |
3650 /// </summary> | |
3651 /// <remarks> | |
3652 /// See the <see cref="ExecuteDataSet(NameOrIndexParameter)"/> method | |
3653 /// to find an example. | |
3654 /// </remarks> | |
3655 /// <returns>The <see cref="DataSet"/>.</returns> | |
3656 public DataSet ExecuteDataSet() | |
3657 { | |
3658 return ExecuteDataSet(null, 0, 0, "Table"); | |
3659 } | |
3660 | |
3661 /// <summary> | |
3662 /// Executes a SQL statement using the provided parameters. | |
3663 /// </summary> | |
3664 /// <remarks> | |
3665 /// See the <see cref="ExecuteDataSet(NameOrIndexParameter)"/> method | |
3666 /// to find an example. | |
3667 /// </remarks> | |
3668 /// <param name="dataSet">The input <see cref="DataSet"/> object.</param> | |
3669 /// <returns>The <see cref="DataSet"/>.</returns> | |
3670 public DataSet ExecuteDataSet( | |
3671 DataSet dataSet) | |
3672 { | |
3673 return ExecuteDataSet(dataSet, 0, 0, "Table"); | |
3674 } | |
3675 | |
3676 /// <summary> | |
3677 /// Executes a SQL statement using the provided parameters. | |
3678 /// </summary> | |
3679 /// <remarks> | |
3680 /// See the <see cref="ExecuteDataSet(NameOrIndexParameter)"/> method | |
3681 /// to find an example. | |
3682 /// </remarks> | |
3683 /// <param name="table">The name or index of the populating table.</param> | |
3684 /// <returns>The <see cref="DataSet"/>.</returns> | |
3685 public DataSet ExecuteDataSet( | |
3686 NameOrIndexParameter table) | |
3687 { | |
3688 return ExecuteDataSet(null, 0, 0, table); | |
3689 } | |
3690 | |
3691 /// <summary> | |
3692 /// Executes a SQL statement using the provided parameters. | |
3693 /// </summary> | |
3694 /// <param name="dataSet">The <see cref="DataSet"/> object to populate.</param> | |
3695 /// <param name="table">The name or index of the populating table.</param> | |
3696 /// <returns>The <see cref="DataSet"/>.</returns> | |
3697 public DataSet ExecuteDataSet( | |
3698 DataSet dataSet, | |
3699 NameOrIndexParameter table) | |
3700 { | |
3701 return ExecuteDataSet(dataSet, 0, 0, table); | |
3702 } | |
3703 | |
3704 /// <summary> | |
3705 /// Executes a SQL statement using the provided parameters. | |
3706 /// </summary> | |
3707 /// <param name="dataSet">The <see cref="DataSet"/> object to populate.</param> | |
3708 /// <param name="table">The name or index of the populating table.</param> | |
3709 /// <param name="startRecord">The zero-based record number to start with.</param> | |
3710 /// <param name="maxRecords">The maximum number of records to retrieve.</param> | |
3711 /// <returns>The <see cref="DataSet"/>.</returns> | |
3712 public DataSet ExecuteDataSet( | |
3713 DataSet dataSet, | |
3714 int startRecord, | |
3715 int maxRecords, | |
3716 NameOrIndexParameter table) | |
3717 { | |
3718 if (_prepared) | |
3719 InitParameters(CommandAction.Select); | |
3720 | |
3721 if (dataSet == null) | |
3722 dataSet = new DataSet(); | |
3723 | |
3724 var da = _dataProvider.CreateDataAdapterObject(); | |
3725 | |
3726 ((IDbDataAdapter)da).SelectCommand = SelectCommand; | |
3727 | |
3728 ExecuteOperation(OperationType.Fill, delegate | |
3729 { | |
3730 if (table.ByName) | |
3731 da.Fill(dataSet, startRecord, maxRecords, table.Name); | |
3732 else | |
3733 da.Fill(startRecord, maxRecords, dataSet.Tables[table.Index]); | |
3734 }); | |
3735 | |
3736 return dataSet; | |
3737 } | |
3738 | |
3739 #endregion | |
3740 | |
3741 #region ExecuteDataTable | |
3742 | |
3743 /// <summary> | |
3744 /// Executes a SQL statement using the provided parameters. | |
3745 /// </summary> | |
3746 /// <returns>The <see cref="DataTable"/>.</returns> | |
3747 public DataTable ExecuteDataTable() | |
3748 { | |
3749 return ExecuteDataTable(null); | |
3750 } | |
3751 | |
3752 /// <summary> | |
3753 /// Executes a SQL statement using the provided parameters. | |
3754 /// </summary> | |
3755 /// <param name="dataTable">The <see cref="DataTable"/> object to populate.</param> | |
3756 /// <returns>The <see cref="DataTable"/>.</returns> | |
3757 public DataTable ExecuteDataTable(DataTable dataTable) | |
3758 { | |
3759 if (_prepared) | |
3760 InitParameters(CommandAction.Select); | |
3761 | |
3762 if (dataTable == null) | |
3763 dataTable = new DataTable(); | |
3764 | |
3765 var da = _dataProvider.CreateDataAdapterObject(); | |
3766 ((IDbDataAdapter)da).SelectCommand = SelectCommand; | |
3767 | |
3768 ExecuteOperation(OperationType.Fill, delegate { da.Fill(dataTable); }); | |
3769 return dataTable; | |
3770 } | |
3771 | |
3772 /// <summary>Adds or refreshes rows in a <see cref="System.Data.DataTable"/> | |
3773 /// to match those in the data source starting at the specified record | |
3774 /// and retrieving up to the specified maximum number of records. | |
3775 /// </summary> | |
3776 /// <param name="startRecord">The zero-based record number to start with.</param> | |
3777 /// <param name="maxRecords">The maximum number of records to retrieve.</param> | |
3778 /// <param name="tableList">The <see cref="System.Data.DataTable"/> objects | |
3779 /// to fill from the data source.</param> | |
3780 public void ExecuteDataTables( | |
3781 int startRecord, | |
3782 int maxRecords, | |
3783 params DataTable[] tableList) | |
3784 { | |
3785 if (tableList == null || tableList.Length == 0) | |
3786 return; | |
3787 | |
3788 if (_prepared) | |
3789 InitParameters(CommandAction.Select); | |
3790 | |
3791 var da = _dataProvider.CreateDataAdapterObject(); | |
3792 ((IDbDataAdapter)da).SelectCommand = SelectCommand; | |
3793 | |
3794 ExecuteOperation(OperationType.Fill, delegate { da.Fill(startRecord, maxRecords, tableList); }); | |
3795 } | |
3796 | |
3797 /// <summary>Adds or refreshes rows in a <see cref="System.Data.DataTable"/> | |
3798 /// to match those in the data source starting at the specified record | |
3799 /// and retrieving up to the specified maximum number of records. | |
3800 /// </summary> | |
3801 /// <param name="tableList">The <see cref="System.Data.DataTable"/> objects | |
3802 /// to fill from the data source.</param> | |
3803 public void ExecuteDataTables(params DataTable[] tableList) | |
3804 { | |
3805 ExecuteDataTables(0, 0, tableList); | |
3806 } | |
3807 | |
3808 #endregion | |
3809 | |
3810 #region ExecuteObject | |
3811 | |
3812 /// <summary> | |
3813 /// Executes a SQL statement and maps resultset to an object. | |
3814 /// </summary> | |
3815 /// <param name="entity">An object to populate.</param> | |
3816 /// <param name="type">The System.Type of the object.</param> | |
3817 /// <param name="parameters">Additional parameters passed to object constructor through <see cref="InitContext"/>.</param> | |
3818 /// <returns>A business object.</returns> | |
3819 private object ExecuteObjectInternal(object entity, Type type, object[] parameters) | |
3820 { | |
3821 if (_prepared) | |
3822 InitParameters(CommandAction.Select); | |
3823 | |
3824 using (var dr = ExecuteReaderInternal(/*CommandBehavior.SingleRow*/)) // Sybase provider does not support this flag. | |
3825 return ExecuteOperation(OperationType.Read, () => | |
3826 { | |
3827 while (dr.Read()) | |
3828 return | |
3829 entity == null | |
3830 ? _mappingSchema.MapDataReaderToObject(dr, type, parameters) | |
3831 : _mappingSchema.MapDataReaderToObject(dr, entity, parameters); | |
3832 | |
3833 return null; | |
3834 }); | |
3835 } | |
3836 | |
3837 /// <summary> | |
3838 /// Executes a SQL statement and maps resultset to an object. | |
3839 /// </summary> | |
3840 /// <param name="entity">An object to populate.</param> | |
3841 /// <returns>A business object.</returns> | |
3842 public object ExecuteObject(object entity) | |
3843 { | |
3844 if (null == entity) | |
3845 throw new ArgumentNullException("entity"); | |
3846 | |
3847 return ExecuteObjectInternal(entity, entity.GetType(), null); | |
3848 } | |
3849 | |
3850 /// <summary> | |
3851 /// Executes a SQL statement and maps resultset to an object. | |
3852 /// </summary> | |
3853 /// <param name="entity">An object to populate.</param> | |
3854 /// <param name="parameters">Additional parameters passed to object constructor through <see cref="InitContext"/>.</param> | |
3855 /// <returns>A business object.</returns> | |
3856 public object ExecuteObject(object entity, params object[] parameters) | |
3857 { | |
3858 if (null == entity) | |
3859 throw new ArgumentNullException("entity"); | |
3860 | |
3861 return ExecuteObjectInternal(entity, entity.GetType(), parameters); | |
3862 } | |
3863 | |
3864 /// <summary> | |
3865 /// Executes a SQL statement and maps resultset to an object. | |
3866 /// </summary> | |
3867 /// <param name="type">Type of an object.</param> | |
3868 /// <returns>A business object.</returns> | |
3869 public object ExecuteObject(Type type) | |
3870 { | |
3871 return ExecuteObjectInternal(null, type, null); | |
3872 } | |
3873 | |
3874 /// <summary> | |
3875 /// Executes a SQL statement and maps resultset to an object. | |
3876 /// </summary> | |
3877 /// <param name="type">Type of an object.</param> | |
3878 /// <param name="parameters">Additional parameters passed to object constructor through <see cref="InitContext"/>.</param> | |
3879 /// <returns>A business object.</returns> | |
3880 public object ExecuteObject(Type type, params object[] parameters) | |
3881 { | |
3882 return ExecuteObjectInternal(null, type, parameters); | |
3883 } | |
3884 | |
3885 /// <summary> | |
3886 /// Executes a SQL statement and maps resultset to an object. | |
3887 /// </summary> | |
3888 /// <typeparam name="T">Type of an object.</typeparam> | |
3889 /// <returns>A business object.</returns> | |
3890 public T ExecuteObject<T>() | |
3891 { | |
3892 return (T)ExecuteObjectInternal(null, typeof(T), null); | |
3893 } | |
3894 | |
3895 /// <summary> | |
3896 /// Executes a SQL statement and maps resultset to an object. | |
3897 /// </summary> | |
3898 /// <typeparam name="T">Type of an object.</typeparam> | |
3899 /// <param name="parameters">Additional parameters passed to object constructor through <see cref="InitContext"/>.</param> | |
3900 /// <returns>A business object.</returns> | |
3901 public T ExecuteObject<T>(params object[] parameters) | |
3902 { | |
3903 return (T)ExecuteObjectInternal(null, typeof(T), parameters); | |
3904 } | |
3905 | |
3906 #endregion | |
3907 | |
3908 #region ExecuteList | |
3909 | |
3910 private IList ExecuteListInternal(IList list, Type type, params object[] parameters) | |
3911 { | |
3912 if (list == null) | |
3913 list = new ArrayList(); | |
3914 | |
3915 if (_prepared) | |
3916 InitParameters(CommandAction.Select); | |
3917 | |
3918 using (var dr = ExecuteReaderInternal()) | |
3919 //wrap this too, because of PostgreSQL lazy query execution | |
3920 return ExecuteOperation(OperationType.Fill, () => _mappingSchema.MapDataReaderToList(dr, list, type, parameters)); | |
3921 } | |
3922 | |
3923 private void ExecuteListInternal<T>(IList<T> list, params object[] parameters) | |
3924 { | |
3925 if (list == null) | |
3926 list = new List<T>(); | |
3927 | |
3928 if (_prepared) | |
3929 InitParameters(CommandAction.Select); | |
3930 | |
3931 using (var dr = ExecuteReaderInternal()) | |
3932 ExecuteOperation(OperationType.Fill, () => _mappingSchema.MapDataReaderToList(dr, list, parameters)); | |
3933 } | |
3934 | |
3935 /// <summary> | |
3936 /// Executes the query, and returns an array of business entities using the provided parameters. | |
3937 /// </summary> | |
3938 /// <param name="type">Type of the business object.</param> | |
3939 /// <returns>An array of business objects.</returns> | |
3940 public ArrayList ExecuteList(Type type) | |
3941 { | |
3942 var arrayList = new ArrayList(); | |
3943 | |
3944 ExecuteListInternal(arrayList, type, null); | |
3945 | |
3946 return arrayList; | |
3947 } | |
3948 | |
3949 /// <summary> | |
3950 /// Executes the query, and returns an array of business entities. | |
3951 /// </summary> | |
3952 /// <typeparam name="T">Type of an object.</typeparam> | |
3953 /// <returns>Populated list of mapped business objects.</returns> | |
3954 public List<T> ExecuteList<T>() | |
3955 { | |
3956 var list = new List<T>(); | |
3957 | |
3958 ExecuteListInternal<T>(list, null); | |
3959 | |
3960 return list; | |
3961 } | |
3962 | |
3963 /// <summary> | |
3964 /// Executes the query, and returns an array of business entities using the provided parameters. | |
3965 /// </summary> | |
3966 /// <param name="type">Type of the business object.</param> | |
3967 /// <param name="parameters">Additional parameters passed to object constructor through <see cref="InitContext"/>.</param> | |
3968 /// <returns>An array of business objects.</returns> | |
3969 public ArrayList ExecuteList(Type type, params object[] parameters) | |
3970 { | |
3971 var arrayList = new ArrayList(); | |
3972 | |
3973 ExecuteListInternal(arrayList, type, parameters); | |
3974 | |
3975 return arrayList; | |
3976 } | |
3977 | |
3978 /// <summary> | |
3979 /// Executes the query, and returns an array of business entities. | |
3980 /// </summary> | |
3981 /// <typeparam name="T">Type of an object.</typeparam> | |
3982 /// <param name="parameters">Additional parameters passed to object constructor through <see cref="InitContext"/>.</param> | |
3983 /// <returns>Populated list of mapped business objects.</returns> | |
3984 public List<T> ExecuteList<T>(params object[] parameters) | |
3985 { | |
3986 var list = new List<T>(); | |
3987 | |
3988 ExecuteListInternal(list, parameters); | |
3989 | |
3990 return list; | |
3991 } | |
3992 | |
3993 /// <summary> | |
3994 /// Executes the query, and returns an array of business entities. | |
3995 /// </summary> | |
3996 /// <param name="list">The list of mapped business objects to populate.</param> | |
3997 /// <param name="type">Type of an object.</param> | |
3998 /// <returns>Populated list of mapped business objects.</returns> | |
3999 public IList ExecuteList(IList list, Type type) | |
4000 { | |
4001 return ExecuteListInternal(list, type, null); | |
4002 } | |
4003 | |
4004 /// <summary> | |
4005 /// Executes the query, and returns an array of business entities. | |
4006 /// </summary> | |
4007 /// <typeparam name="T">Type of an object.</typeparam> | |
4008 /// <param name="list">The list of mapped business objects to populate.</param> | |
4009 /// <returns>Populated list of mapped business objects.</returns> | |
4010 public IList<T> ExecuteList<T>(IList<T> list) | |
4011 { | |
4012 ExecuteListInternal(list, null); | |
4013 | |
4014 return list; | |
4015 } | |
4016 | |
4017 /// <summary> | |
4018 /// Executes the query, and returns an array of business entities. | |
4019 /// </summary> | |
4020 /// <param name="list">The list of mapped business objects to populate.</param> | |
4021 /// <param name="type">Type of an object.</param> | |
4022 /// <param name="parameters">Additional parameters passed to object constructor through <see cref="InitContext"/>.</param> | |
4023 /// <returns>Populated list of mapped business objects.</returns> | |
4024 public IList ExecuteList(IList list, Type type, params object[] parameters) | |
4025 { | |
4026 return ExecuteListInternal(list, type, parameters); | |
4027 } | |
4028 | |
4029 /// <summary> | |
4030 /// Executes the query, and returns an array of business entities. | |
4031 /// </summary> | |
4032 /// <typeparam name="T">Type of an object.</typeparam> | |
4033 /// <param name="list">The list of mapped business objects to populate.</param> | |
4034 /// <param name="parameters">Additional parameters passed to object constructor through <see cref="InitContext"/>.</param> | |
4035 /// <returns>Populated list of mapped business objects.</returns> | |
4036 public IList<T> ExecuteList<T>(IList<T> list, params object[] parameters) | |
4037 { | |
4038 ExecuteListInternal(list, parameters); | |
4039 | |
4040 return list; | |
4041 } | |
4042 | |
4043 /// <summary> | |
4044 /// Executes the query, and returns an array of business entities. | |
4045 /// </summary> | |
4046 /// <typeparam name="TList">Type of a list.</typeparam> | |
4047 /// <typeparam name="T">Type of an object.</typeparam> | |
4048 /// <param name="list">The list of mapped business objects to populate.</param> | |
4049 /// <param name="parameters">Additional parameters passed to object constructor through <see cref="InitContext"/>.</param> | |
4050 /// <returns>Populated list of mapped business objects.</returns> | |
4051 public TList ExecuteList<TList,T>(TList list, params object[] parameters) | |
4052 where TList : IList<T> | |
4053 { | |
4054 ExecuteListInternal(list, typeof(T), parameters); | |
4055 | |
4056 return list; | |
4057 } | |
4058 | |
4059 /// <summary> | |
4060 /// Executes the query, and returns an array of business entities. | |
4061 /// </summary> | |
4062 /// <typeparam name="TList">Type of a list.</typeparam> | |
4063 /// <typeparam name="T">Type of an object.</typeparam> | |
4064 /// <param name="parameters">Additional parameters passed to object constructor through <see cref="InitContext"/>.</param> | |
4065 /// <returns>Populated list of mapped business objects.</returns> | |
4066 public TList ExecuteList<TList,T>(params object[] parameters) | |
4067 where TList : IList<T>, new() | |
4068 { | |
4069 var list = new TList(); | |
4070 | |
4071 ExecuteListInternal(list, typeof(T), parameters); | |
4072 | |
4073 return list; | |
4074 } | |
4075 | |
4076 #endregion | |
4077 | |
4078 #region ExecuteDictionary | |
4079 | |
4080 /// <summary> | |
4081 /// Executes the query, and returns the <see cref="Hashtable"/> of business entities | |
4082 /// using the provided parameters. | |
4083 /// </summary> | |
4084 /// <include file="Examples.xml" path='examples/db[@name="ExecuteDictionary(string,Type)"]/*' /> | |
4085 /// <param name="keyField">The field name or index that is used as a key to populate <see cref="Hashtable"/>.</param> | |
4086 /// <param name="keyFieldType">Business object type.</param> | |
4087 /// <param name="parameters">Any additional parameters passed to the constructor with <see cref="InitContext"/> parameter.</param> | |
4088 /// <returns>An instance of the <see cref="Hashtable"/> class.</returns> | |
4089 public Hashtable ExecuteDictionary( | |
4090 NameOrIndexParameter keyField, | |
4091 Type keyFieldType, | |
4092 params object[] parameters) | |
4093 { | |
4094 var hash = new Hashtable(); | |
4095 | |
4096 ExecuteDictionary(hash, keyField, keyFieldType, parameters); | |
4097 | |
4098 return hash; | |
4099 } | |
4100 | |
4101 /// <summary> | |
4102 /// Executes the query, and returns the <see cref="Hashtable"/> of business entities. | |
4103 /// </summary> | |
4104 /// <include file="Examples.xml" path='examples/db[@name="ExecuteDictionary(Hashtable,string,Type)"]/*' /> | |
4105 /// <param name="dictionary">A dictionary of mapped business objects to populate.</param> | |
4106 /// <param name="keyField">The field name or index that is used as a key to populate <see cref="IDictionary"/>.</param> | |
4107 /// <param name="type">Business object type.</param> | |
4108 /// <param name="parameters">Any additional parameters passed to the constructor with <see cref="InitContext"/> parameter.</param> | |
4109 /// <returns>An instance of the <see cref="IDictionary"/>.</returns> | |
4110 public IDictionary ExecuteDictionary( | |
4111 IDictionary dictionary, | |
4112 NameOrIndexParameter keyField, | |
4113 Type type, | |
4114 params object[] parameters) | |
4115 { | |
4116 if (dictionary == null) | |
4117 dictionary = new Hashtable(); | |
4118 | |
4119 if (_prepared) | |
4120 InitParameters(CommandAction.Select); | |
4121 | |
4122 using (var dr = ExecuteReaderInternal()) | |
4123 return _mappingSchema.MapDataReaderToDictionary(dr, dictionary, keyField, type, parameters); | |
4124 } | |
4125 | |
4126 /// <summary> | |
4127 /// Executes the query, and returns a dictionary of business entities. | |
4128 /// </summary> | |
4129 /// <typeparam name="TKey">Key's type.</typeparam> | |
4130 /// <typeparam name="TValue">Value's type.</typeparam> | |
4131 /// <param name="keyField">The field name or index that is used as a key to populate the dictionary.</param> | |
4132 /// <param name="parameters">Any additional parameters passed to the constructor with <see cref="InitContext"/> parameter.</param> | |
4133 /// <returns>An instance of the dictionary.</returns> | |
4134 public Dictionary<TKey, TValue> ExecuteDictionary<TKey, TValue>( | |
4135 NameOrIndexParameter keyField, | |
4136 params object[] parameters) | |
4137 { | |
4138 var dictionary = new Dictionary<TKey, TValue>(); | |
4139 | |
4140 ExecuteDictionary<TKey, TValue>(dictionary, keyField, typeof(TValue), parameters); | |
4141 | |
4142 return dictionary; | |
4143 } | |
4144 | |
4145 /// <summary> | |
4146 /// Executes the query, and returns the <see cref="Hashtable"/> of business entities. | |
4147 /// </summary> | |
4148 /// <param name="dictionary">A dictionary of mapped business objects to populate.</param> | |
4149 /// <param name="keyField">The field name or index that is used as a key to populate <see cref="IDictionary"/>.</param> | |
4150 /// <param name="parameters">Any additional parameters passed to the constructor with <see cref="InitContext"/> parameter.</param> | |
4151 /// <returns>An instance of the <see cref="IDictionary"/>.</returns> | |
4152 public IDictionary<TKey, TValue> ExecuteDictionary<TKey, TValue>( | |
4153 IDictionary<TKey, TValue> dictionary, | |
4154 NameOrIndexParameter keyField, | |
4155 params object[] parameters) | |
4156 { | |
4157 return ExecuteDictionary(dictionary, keyField, typeof(TValue), parameters); | |
4158 } | |
4159 | |
4160 /// <summary> | |
4161 /// Executes the query, and returns the <see cref="Hashtable"/> of business entities. | |
4162 /// </summary> | |
4163 /// <param name="dictionary">A dictionary of mapped business objects to populate.</param> | |
4164 /// <param name="keyField">The field name or index that is used as a key to populate <see cref="IDictionary"/>.</param> | |
4165 /// <param name="destObjectType">Business object type.</param> | |
4166 /// <param name="parameters">Any additional parameters passed to the constructor with <see cref="InitContext"/> parameter.</param> | |
4167 /// <returns>An instance of the <see cref="IDictionary"/>.</returns> | |
4168 public IDictionary<TKey, TValue> ExecuteDictionary<TKey, TValue>( | |
4169 IDictionary<TKey, TValue> dictionary, | |
4170 NameOrIndexParameter keyField, | |
4171 Type destObjectType, | |
4172 params object[] parameters) | |
4173 { | |
4174 if (dictionary == null) | |
4175 dictionary = new Dictionary<TKey, TValue>(); | |
4176 | |
4177 if (_prepared) | |
4178 InitParameters(CommandAction.Select); | |
4179 | |
4180 using (var dr = ExecuteReaderInternal()) | |
4181 return _mappingSchema.MapDataReaderToDictionary( | |
4182 dr, dictionary, keyField, destObjectType, parameters); | |
4183 } | |
4184 | |
4185 #endregion | |
4186 | |
4187 #region ExecuteDictionary (Index) | |
4188 | |
4189 /// <summary> | |
4190 /// Executes the query, and returns the <see cref="Hashtable"/> of business entities | |
4191 /// using the provided parameters. | |
4192 /// </summary> | |
4193 /// <include file="Examples.xml" path='examples/db[@name="ExecuteDictionary(string,Type)"]/*' /> | |
4194 /// <param name="index">Dictionary key fields.</param> | |
4195 /// <param name="type">Business object type.</param> | |
4196 /// <param name="parameters">Any additional parameters passed to the constructor with <see cref="InitContext"/> parameter.</param> | |
4197 /// <returns>An instance of the <see cref="Hashtable"/> class.</returns> | |
4198 public Hashtable ExecuteDictionary( | |
4199 MapIndex index, | |
4200 Type type, | |
4201 params object[] parameters) | |
4202 { | |
4203 var hash = new Hashtable(); | |
4204 | |
4205 ExecuteDictionary(hash, index, type, parameters); | |
4206 | |
4207 return hash; | |
4208 } | |
4209 | |
4210 /// <summary> | |
4211 /// Executes the query, and returns the <see cref="Hashtable"/> of business entities. | |
4212 /// </summary> | |
4213 /// <include file="Examples.xml" path='examples/db[@name="ExecuteDictionary(Hashtable,string,Type)"]/*' /> | |
4214 /// <param name="dictionary">A dictionary of mapped business objects to populate.</param> | |
4215 /// <param name="index">Dictionary key fields.</param> | |
4216 /// <param name="type">Business object type.</param> | |
4217 /// <param name="parameters">Any additional parameters passed to the constructor with <see cref="InitContext"/> parameter.</param> | |
4218 /// <returns>An instance of the <see cref="IDictionary"/>.</returns> | |
4219 public IDictionary ExecuteDictionary( | |
4220 IDictionary dictionary, | |
4221 MapIndex index, | |
4222 Type type, | |
4223 params object[] parameters) | |
4224 { | |
4225 if (dictionary == null) | |
4226 dictionary = new Hashtable(); | |
4227 | |
4228 if (_prepared) | |
4229 InitParameters(CommandAction.Select); | |
4230 | |
4231 using (var dr = ExecuteReaderInternal()) | |
4232 return _mappingSchema.MapDataReaderToDictionary(dr, dictionary, index, type, parameters); | |
4233 } | |
4234 | |
4235 /// <summary> | |
4236 /// Executes the query, and returns a dictionary of business entities. | |
4237 /// </summary> | |
4238 /// <typeparam name="TValue">Value's type.</typeparam> | |
4239 /// <param name="index">Dictionary key fields.</param> | |
4240 /// <param name="parameters">Any additional parameters passed to the constructor with <see cref="InitContext"/> parameter.</param> | |
4241 /// <returns>An instance of the dictionary.</returns> | |
4242 public Dictionary<CompoundValue, TValue> ExecuteDictionary<TValue>( | |
4243 MapIndex index, | |
4244 params object[] parameters) | |
4245 { | |
4246 var dictionary = new Dictionary<CompoundValue, TValue>(); | |
4247 | |
4248 ExecuteDictionary<TValue>(dictionary, index, typeof(TValue), parameters); | |
4249 | |
4250 return dictionary; | |
4251 } | |
4252 | |
4253 /// <summary> | |
4254 /// Executes the query, and returns a dictionary of business entities. | |
4255 /// </summary> | |
4256 /// <typeparam name="TValue">Value's type.</typeparam> | |
4257 /// <param name="dictionary">A dictionary of mapped business objects to populate.</param> | |
4258 /// <param name="index">Dictionary key fields.</param> | |
4259 /// <param name="parameters">Any additional parameters passed to the constructor with <see cref="InitContext"/> parameter.</param> | |
4260 /// <returns>An instance of the dictionary.</returns> | |
4261 public IDictionary<CompoundValue, TValue> ExecuteDictionary<TValue>( | |
4262 IDictionary<CompoundValue, TValue> dictionary, | |
4263 MapIndex index, | |
4264 params object[] parameters) | |
4265 { | |
4266 return ExecuteDictionary(dictionary, index, typeof(TValue), parameters); | |
4267 } | |
4268 | |
4269 /// <summary> | |
4270 /// Executes the query, and returns a dictionary of business entities. | |
4271 /// </summary> | |
4272 /// <typeparam name="TValue">Value's type.</typeparam> | |
4273 /// <param name="dictionary">A dictionary of mapped business objects to populate.</param> | |
4274 /// <param name="index">Dictionary key fields.</param> | |
4275 /// <param name="destObjectType">Business object type.</param> | |
4276 /// <param name="parameters">Any additional parameters passed to the constructor with <see cref="InitContext"/> parameter.</param> | |
4277 /// <returns>An instance of the dictionary.</returns> | |
4278 public IDictionary<CompoundValue, TValue> ExecuteDictionary<TValue>( | |
4279 IDictionary<CompoundValue, TValue> dictionary, | |
4280 MapIndex index, | |
4281 Type destObjectType, | |
4282 params object[] parameters) | |
4283 { | |
4284 if (dictionary == null) | |
4285 dictionary = new Dictionary<CompoundValue, TValue>(); | |
4286 | |
4287 if (_prepared) | |
4288 InitParameters(CommandAction.Select); | |
4289 | |
4290 using (var dr = ExecuteReaderInternal()) | |
4291 return _mappingSchema.MapDataReaderToDictionary( | |
4292 dr, dictionary, index, destObjectType, parameters); | |
4293 } | |
4294 | |
4295 #endregion | |
4296 | |
4297 #region ExecuteResultSet | |
4298 | |
4299 /// <summary> | |
4300 /// Executes the query, and returns multiple results. | |
4301 /// </summary> | |
4302 /// <param name="resultSets">Array of <see cref="MapResultSet"/> to populate.</param> | |
4303 /// <returns>The populated <see cref="MapResultSet"/>.</returns> | |
4304 public MapResultSet[] ExecuteResultSet(params MapResultSet[] resultSets) | |
4305 { | |
4306 if (_prepared) | |
4307 InitParameters(CommandAction.Select); | |
4308 | |
4309 using (var dr = ExecuteReaderInternal()) | |
4310 _mappingSchema.MapDataReaderToResultSet(dr, resultSets); | |
4311 | |
4312 return resultSets; | |
4313 } | |
4314 | |
4315 /// <summary> | |
4316 /// Executes the query, and returns multiple results. | |
4317 /// </summary> | |
4318 /// <param name="masterType">The type of the master business object.</param> | |
4319 /// <param name="nextResults">Array of <see cref="MapNextResult"/> to populate.</param> | |
4320 /// <returns>The populated <see cref="MapResultSet"/>.</returns> | |
4321 public MapResultSet[] ExecuteResultSet( | |
4322 Type masterType, params MapNextResult[] nextResults) | |
4323 { | |
4324 return ExecuteResultSet(_mappingSchema.ConvertToResultSet(masterType, nextResults)); | |
4325 } | |
4326 | |
4327 /// <summary> | |
4328 /// Executes the query, and returns multiple results. | |
4329 /// </summary> | |
4330 /// <typeparam name="T">The type of the master business object.</typeparam> | |
4331 /// <param name="nextResults">Array of <see cref="MapNextResult"/> to populate.</param> | |
4332 /// <returns>The populated <see cref="MapResultSet"/>.</returns> | |
4333 public MapResultSet[] ExecuteResultSet<T>(params MapNextResult[] nextResults) | |
4334 { | |
4335 return ExecuteResultSet(_mappingSchema.ConvertToResultSet(typeof(T), nextResults)); | |
4336 } | |
4337 | |
4338 #endregion | |
4339 | |
4340 #region Update | |
4341 | |
4342 private DbDataAdapter CreateDataAdapter() | |
4343 { | |
4344 var da = _dataProvider.CreateDataAdapterObject(); | |
4345 | |
4346 if (_insertCommand != null) ((IDbDataAdapter)da).InsertCommand = InsertCommand; | |
4347 if (_updateCommand != null) ((IDbDataAdapter)da).UpdateCommand = UpdateCommand; | |
4348 if (_deleteCommand != null) ((IDbDataAdapter)da).DeleteCommand = DeleteCommand; | |
4349 | |
4350 return da; | |
4351 } | |
4352 | |
4353 /// <summary> | |
4354 /// Calls the corresponding INSERT, UPDATE, or DELETE statements for each inserted, updated, or | |
4355 /// deleted row in the specified <see cref="DataSet"/>. | |
4356 /// </summary> | |
4357 /// <param name="dataSet">The <see cref="DataSet"/> used to update the data source.</param> | |
4358 /// <returns>The number of rows successfully updated from the <see cref="DataSet"/>.</returns> | |
4359 public int Update(DataSet dataSet) | |
4360 { | |
4361 return Update(dataSet, "Table"); | |
4362 } | |
4363 | |
4364 /// <summary> | |
4365 /// Calls the corresponding INSERT, UPDATE, or DELETE statements for each inserted, updated, or | |
4366 /// deleted row in the <see cref="DataSet"/> with the specified <see cref="DataTable"/> name. | |
4367 /// </summary> | |
4368 /// <param name="dataSet">The <see cref="DataSet"/> used to update the data source.</param> | |
4369 /// <param name="table">The name or index of the source table to use for table mapping.</param> | |
4370 /// <returns>The number of rows successfully updated from the <see cref="DataSet"/>.</returns> | |
4371 public int Update( | |
4372 DataSet dataSet, | |
4373 NameOrIndexParameter table) | |
4374 { | |
4375 if (dataSet == null) | |
4376 throw new ArgumentNullException( | |
4377 "dataSet", Resources.DbManager_CannotUpdateNullDataset); | |
4378 | |
4379 var da = CreateDataAdapter(); | |
4380 | |
4381 return | |
4382 ExecuteOperation( | |
4383 OperationType.Update, | |
4384 () => | |
4385 (table.ByName) | |
4386 ? da.Update(dataSet, table.Name) | |
4387 : da.Update(dataSet.Tables[table.Index])); | |
4388 } | |
4389 | |
4390 /// <summary> | |
4391 /// Calls the corresponding INSERT, UPDATE, or DELETE statements for | |
4392 /// each inserted, updated, or deleted row in the specified | |
4393 /// <see cref="DataTable"/>. | |
4394 /// </summary> | |
4395 /// <param name="dataTable">The name or index of the source table to | |
4396 /// use for table mapping.</param> | |
4397 /// <returns>The number of rows successfully updated from the | |
4398 /// <see cref="DataTable"/>.</returns> | |
4399 public int Update(DataTable dataTable) | |
4400 { | |
4401 if (dataTable == null) | |
4402 throw new ArgumentNullException( | |
4403 "dataTable", Resources.DbManager_CannotUpdateNullDataTable); | |
4404 | |
4405 return | |
4406 ExecuteOperation( | |
4407 OperationType.Update, | |
4408 () => CreateDataAdapter().Update(dataTable)); | |
4409 } | |
4410 | |
4411 #endregion | |
4412 | |
4413 #region ExecuteOperation | |
4414 | |
4415 private void ExecuteOperation(OperationType operationType, Action operation) | |
4416 { | |
4417 try | |
4418 { | |
4419 OnBeforeOperation(operationType); | |
4420 operation(); | |
4421 OnAfterOperation (operationType); | |
4422 } | |
4423 catch (Exception ex) | |
4424 { | |
4425 HandleOperationException(operationType, ex); | |
4426 throw; | |
4427 } | |
4428 } | |
4429 | |
4430 private T ExecuteOperation<T>(OperationType operationType, Func<T> operation) | |
4431 { | |
4432 var res = default(T); | |
4433 | |
4434 try | |
4435 { | |
4436 OnBeforeOperation(operationType); | |
4437 res = operation(); | |
4438 OnAfterOperation (operationType); | |
4439 } | |
4440 catch (Exception ex) | |
4441 { | |
4442 if (res is IDisposable) | |
4443 ((IDisposable)res).Dispose(); | |
4444 | |
4445 HandleOperationException(operationType, ex); | |
4446 throw; | |
4447 } | |
4448 | |
4449 return res; | |
4450 } | |
4451 | |
4452 private void HandleOperationException(OperationType op, Exception ex) | |
4453 { | |
4454 var dex = new DataException(this, ex); | |
4455 | |
4456 if (TraceSwitch.TraceError) | |
4457 WriteTraceLine(string.Format("Operation '{0}' throws exception '{1}'", op, dex), TraceSwitch.DisplayName); | |
4458 | |
4459 OnOperationException(op, dex); | |
4460 } | |
4461 | |
4462 #endregion | |
4463 | |
4464 #region IDisposable interface | |
4465 | |
4466 /// <summary> | |
4467 /// Releases the unmanaged resources used by the <see cref="DbManager"/> and | |
4468 /// optionally releases the managed resources. | |
4469 /// </summary> | |
4470 /// <remarks> | |
4471 /// This method is called by the public <see cref="IDisposable.Dispose()"/> method | |
4472 /// and the Finalize method. | |
4473 /// </remarks> | |
4474 /// <param name="disposing"><b>true</b> to release both managed and unmanaged resources; <b>false</b> to release only unmanaged resources.</param> | |
4475 protected override void Dispose(bool disposing) | |
4476 { | |
4477 if (disposing) | |
4478 Close(); | |
4479 | |
4480 base.Dispose(disposing); | |
4481 } | |
4482 | |
4483 #endregion | |
4484 } | |
4485 } |