2
0

DbCommandBuilder.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644
  1. //
  2. // System.Data.Common.DbCommandBuilder
  3. //
  4. // Author:
  5. // Tim Coleman ([email protected])
  6. //
  7. // Copyright (C) Tim Coleman, 2003
  8. //
  9. //
  10. // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
  11. //
  12. // Permission is hereby granted, free of charge, to any person obtaining
  13. // a copy of this software and associated documentation files (the
  14. // "Software"), to deal in the Software without restriction, including
  15. // without limitation the rights to use, copy, modify, merge, publish,
  16. // distribute, sublicense, and/or sell copies of the Software, and to
  17. // permit persons to whom the Software is furnished to do so, subject to
  18. // the following conditions:
  19. //
  20. // The above copyright notice and this permission notice shall be
  21. // included in all copies or substantial portions of the Software.
  22. //
  23. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  24. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  25. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  26. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  27. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  28. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  29. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  30. //
  31. #if NET_2_0 || TARGET_JVM
  32. using System.ComponentModel;
  33. using System.Data;
  34. using System.Globalization;
  35. using System.Text;
  36. namespace System.Data.Common {
  37. public abstract class DbCommandBuilder : Component
  38. {
  39. bool _setAllValues;
  40. bool _disposed;
  41. DataTable _dbSchemaTable;
  42. DbDataAdapter _dbDataAdapter;
  43. private CatalogLocation _catalogLocation = CatalogLocation.Start;
  44. private ConflictOption _conflictOption = ConflictOption.CompareAllSearchableValues;
  45. private string _tableName;
  46. private string _catalogSeparator;
  47. private string _quotePrefix;
  48. private string _quoteSuffix;
  49. private string _schemaSeparator;
  50. private DbCommand _dbCommand;
  51. DbCommand _deleteCommand;
  52. DbCommand _insertCommand;
  53. DbCommand _updateCommand;
  54. static readonly string SEPARATOR_DEFAULT = ".";
  55. // Used to construct WHERE clauses
  56. static readonly string clause1 = "({0} = 1 AND {1} IS NULL)";
  57. static readonly string clause2 = "({0} = {1})";
  58. protected DbCommandBuilder ()
  59. {
  60. }
  61. private void BuildCache (bool closeConnection)
  62. {
  63. DbCommand sourceCommand = SourceCommand;
  64. if (sourceCommand == null)
  65. throw new InvalidOperationException ("The DataAdapter.SelectCommand property needs to be initialized.");
  66. DbConnection connection = sourceCommand.Connection;
  67. if (connection == null)
  68. throw new InvalidOperationException ("The DataAdapter.SelectCommand.Connection property needs to be initialized.");
  69. if (_dbSchemaTable == null) {
  70. if (connection.State == ConnectionState.Open)
  71. closeConnection = false;
  72. else
  73. connection.Open ();
  74. DbDataReader reader = sourceCommand.ExecuteReader (CommandBehavior.SchemaOnly | CommandBehavior.KeyInfo);
  75. _dbSchemaTable = reader.GetSchemaTable ();
  76. reader.Close ();
  77. if (closeConnection)
  78. connection.Close ();
  79. BuildInformation (_dbSchemaTable);
  80. }
  81. }
  82. private string QuotedTableName {
  83. get { return GetQuotedString (_tableName); }
  84. }
  85. bool IsCommandGenerated {
  86. get {
  87. return (_insertCommand != null || _updateCommand != null || _deleteCommand != null);
  88. }
  89. }
  90. private string GetQuotedString (string value)
  91. {
  92. if (value == String.Empty || value == null)
  93. return value;
  94. string prefix = QuotePrefix;
  95. string suffix = QuoteSuffix;
  96. if (prefix.Length == 0 && suffix.Length == 0)
  97. return value;
  98. return String.Format ("{0}{1}{2}", prefix, value, suffix);
  99. }
  100. private void BuildInformation (DataTable schemaTable)
  101. {
  102. _tableName = String.Empty;
  103. foreach (DataRow schemaRow in schemaTable.Rows) {
  104. if (schemaRow.IsNull ("BaseTableName") || (string) schemaRow ["BaseTableName"] == String.Empty)
  105. continue;
  106. if (_tableName == String.Empty)
  107. _tableName = (string) schemaRow ["BaseTableName"];
  108. else if (_tableName != (string) schemaRow["BaseTableName"])
  109. throw new InvalidOperationException ("Dynamic SQL generation is not supported against multiple base tables.");
  110. }
  111. if (_tableName == String.Empty)
  112. throw new InvalidOperationException ("Dynamic SQL generation is not supported with no base table.");
  113. _dbSchemaTable = schemaTable;
  114. }
  115. private bool IncludedInInsert (DataRow schemaRow)
  116. {
  117. // If the parameter has one of these properties, then we don't include it in the insert:
  118. // AutoIncrement, Hidden, Expression, RowVersion, ReadOnly
  119. if (!schemaRow.IsNull ("IsAutoIncrement") && (bool) schemaRow ["IsAutoIncrement"])
  120. return false;
  121. // if (!schemaRow.IsNull ("IsHidden") && (bool) schemaRow ["IsHidden"])
  122. // return false;
  123. if (!schemaRow.IsNull ("IsExpression") && (bool) schemaRow ["IsExpression"])
  124. return false;
  125. if (!schemaRow.IsNull ("IsRowVersion") && (bool) schemaRow ["IsRowVersion"])
  126. return false;
  127. if (!schemaRow.IsNull ("IsReadOnly") && (bool) schemaRow ["IsReadOnly"])
  128. return false;
  129. return true;
  130. }
  131. private bool IncludedInUpdate (DataRow schemaRow)
  132. {
  133. // If the parameter has one of these properties, then we don't include it in the insert:
  134. // AutoIncrement, Hidden, RowVersion
  135. if (!schemaRow.IsNull ("IsAutoIncrement") && (bool) schemaRow ["IsAutoIncrement"])
  136. return false;
  137. // if (!schemaRow.IsNull ("IsHidden") && (bool) schemaRow ["IsHidden"])
  138. // return false;
  139. if (!schemaRow.IsNull ("IsRowVersion") && (bool) schemaRow ["IsRowVersion"])
  140. return false;
  141. if (!schemaRow.IsNull ("IsExpression") && (bool) schemaRow ["IsExpression"])
  142. return false;
  143. if (!schemaRow.IsNull ("IsReadOnly") && (bool) schemaRow ["IsReadOnly"])
  144. return false;
  145. return true;
  146. }
  147. private bool IncludedInWhereClause (DataRow schemaRow)
  148. {
  149. if ((bool) schemaRow ["IsLong"])
  150. return false;
  151. return true;
  152. }
  153. private DbCommand CreateDeleteCommand (bool option)
  154. {
  155. // If no table was found, then we can't do an delete
  156. if (QuotedTableName == String.Empty)
  157. return null;
  158. CreateNewCommand (ref _deleteCommand);
  159. string command = String.Format ("DELETE FROM {0}", QuotedTableName);
  160. StringBuilder whereClause = new StringBuilder ();
  161. bool keyFound = false;
  162. int parmIndex = 1;
  163. foreach (DataRow schemaRow in _dbSchemaTable.Rows) {
  164. if (!schemaRow.IsNull ("IsExpression") && (bool)schemaRow["IsExpression"] == true)
  165. continue;
  166. if (!IncludedInWhereClause (schemaRow))
  167. continue;
  168. if (whereClause.Length > 0)
  169. whereClause.Append (" AND ");
  170. bool isKey = (bool) schemaRow ["IsKey"];
  171. DbParameter parameter = null;
  172. if (isKey)
  173. keyFound = true;
  174. //ms.net 1.1 generates the null check for columns even if AllowDBNull is false
  175. //while ms.net 2.0 does not. Anyways, since both forms are logically equivalent
  176. //following the 2.0 approach
  177. bool allowNull = (bool) schemaRow ["AllowDBNull"];
  178. if (!isKey && allowNull) {
  179. parameter = _deleteCommand.CreateParameter ();
  180. if (option) {
  181. parameter.ParameterName = String.Format ("@IsNull_{0}",
  182. schemaRow ["BaseColumnName"]);
  183. } else {
  184. parameter.ParameterName = String.Format ("@p{0}", parmIndex++);
  185. }
  186. String sourceColumnName = (string) schemaRow ["BaseColumnName"];
  187. parameter.Value = 1;
  188. parameter.DbType = DbType.Int32;
  189. // This should be set for nullcheckparam
  190. parameter.SourceColumnNullMapping = true;
  191. _deleteCommand.Parameters.Add (parameter);
  192. whereClause.Append ("(");
  193. whereClause.Append (String.Format (clause1, parameter.ParameterName,
  194. GetQuotedString (sourceColumnName)));
  195. whereClause.Append (" OR ");
  196. }
  197. parameter = CreateParameter (_deleteCommand, String.Format ("@{0}", option ? schemaRow ["BaseColumnName"] : "p" + parmIndex++), schemaRow);
  198. parameter.SourceVersion = DataRowVersion.Original;
  199. whereClause.Append (String.Format (clause2, GetQuotedString (parameter.SourceColumn), parameter.ParameterName));
  200. if (!isKey && allowNull)
  201. whereClause.Append (")");
  202. }
  203. if (!keyFound)
  204. throw new InvalidOperationException ("Dynamic SQL generation for the DeleteCommand is not supported against a SelectCommand that does not return any key column information.");
  205. // We're all done, so bring it on home
  206. string sql = String.Format ("{0} WHERE ({1})", command, whereClause.ToString ());
  207. _deleteCommand.CommandText = sql;
  208. _dbCommand = _deleteCommand;
  209. return _deleteCommand;
  210. }
  211. private DbCommand CreateInsertCommand (bool option)
  212. {
  213. if (QuotedTableName == String.Empty)
  214. return null;
  215. CreateNewCommand (ref _insertCommand);
  216. string command = String.Format ("INSERT INTO {0}", QuotedTableName);
  217. string sql;
  218. StringBuilder columns = new StringBuilder ();
  219. StringBuilder values = new StringBuilder ();
  220. int parmIndex = 1;
  221. foreach (DataRow schemaRow in _dbSchemaTable.Rows) {
  222. if (!IncludedInInsert (schemaRow))
  223. continue;
  224. if (columns.Length > 0) {
  225. columns.Append (", ");
  226. values.Append (", ");
  227. }
  228. DbParameter parameter = CreateParameter (_insertCommand, String.Format ("@{0}", option ? schemaRow ["BaseColumnName"] : "p" + parmIndex++), schemaRow);
  229. parameter.SourceVersion = DataRowVersion.Current;
  230. columns.Append (GetQuotedString (parameter.SourceColumn));
  231. values.Append (parameter.ParameterName);
  232. }
  233. sql = String.Format ("{0} ({1}) VALUES ({2})", command, columns.ToString (), values.ToString ());
  234. _insertCommand.CommandText = sql;
  235. _dbCommand = _insertCommand;
  236. return _insertCommand;
  237. }
  238. private void CreateNewCommand (ref DbCommand command)
  239. {
  240. DbCommand sourceCommand = SourceCommand;
  241. if (command == null) {
  242. command = sourceCommand.Connection.CreateCommand ();
  243. command.CommandTimeout = sourceCommand.CommandTimeout;
  244. command.Transaction = sourceCommand.Transaction;
  245. }
  246. command.CommandType = CommandType.Text;
  247. command.UpdatedRowSource = UpdateRowSource.None;
  248. command.Parameters.Clear ();
  249. }
  250. private DbCommand CreateUpdateCommand (bool option)
  251. {
  252. // If no table was found, then we can't do an update
  253. if (QuotedTableName == String.Empty)
  254. return null;
  255. CreateNewCommand (ref _updateCommand);
  256. string command = String.Format ("UPDATE {0} SET ", QuotedTableName);
  257. StringBuilder columns = new StringBuilder ();
  258. StringBuilder whereClause = new StringBuilder ();
  259. int parmIndex = 1;
  260. bool keyFound = false;
  261. // First, create the X=Y list for UPDATE
  262. foreach (DataRow schemaRow in _dbSchemaTable.Rows) {
  263. if (!IncludedInUpdate (schemaRow))
  264. continue;
  265. if (columns.Length > 0)
  266. columns.Append (", ");
  267. DbParameter parameter = CreateParameter (_updateCommand, String.Format ("@{0}", option ? schemaRow ["BaseColumnName"] : "p" + parmIndex++), schemaRow);
  268. parameter.SourceVersion = DataRowVersion.Current;
  269. columns.Append (String.Format ("{0} = {1}", GetQuotedString (parameter.SourceColumn), parameter.ParameterName));
  270. }
  271. // Now, create the WHERE clause. This may be optimizable, but it would be ugly to incorporate
  272. // into the loop above. "Premature optimization is the root of all evil." -- Knuth
  273. foreach (DataRow schemaRow in _dbSchemaTable.Rows) {
  274. if (!schemaRow.IsNull ("IsExpression") && (bool) schemaRow ["IsExpression"] == true)
  275. continue;
  276. if (!IncludedInWhereClause (schemaRow))
  277. continue;
  278. if (whereClause.Length > 0)
  279. whereClause.Append (" AND ");
  280. bool isKey = (bool) schemaRow ["IsKey"];
  281. DbParameter parameter = null;
  282. if (isKey)
  283. keyFound = true;
  284. //ms.net 1.1 generates the null check for columns even if AllowDBNull is false
  285. //while ms.net 2.0 does not. Anyways, since both forms are logically equivalent
  286. //following the 2.0 approach
  287. bool allowNull = (bool) schemaRow ["AllowDBNull"];
  288. if (!isKey && allowNull) {
  289. parameter = _updateCommand.CreateParameter ();
  290. if (option) {
  291. parameter.ParameterName = String.Format ("@IsNull_{0}",
  292. schemaRow ["BaseColumnName"]);
  293. } else {
  294. parameter.ParameterName = String.Format ("@p{0}", parmIndex++);
  295. }
  296. parameter.DbType = DbType.Int32;
  297. parameter.Value = 1;
  298. // This should be set for nullcheckparam
  299. parameter.SourceColumnNullMapping = true;
  300. whereClause.Append ("(");
  301. whereClause.Append (String.Format (clause1, parameter.ParameterName,
  302. GetQuotedString ((string) schemaRow ["BaseColumnName"])));
  303. whereClause.Append (" OR ");
  304. _updateCommand.Parameters.Add (parameter);
  305. }
  306. if (option)
  307. parameter = CreateParameter (_updateCommand, String.Format ("@Original_{0}", schemaRow ["BaseColumnName"]), schemaRow);
  308. else
  309. parameter = CreateParameter (_updateCommand, String.Format ("@p{0}", parmIndex++), schemaRow);
  310. parameter.SourceVersion = DataRowVersion.Original;
  311. whereClause.Append (String.Format (clause2, GetQuotedString (parameter.SourceColumn), parameter.ParameterName));
  312. if (!isKey && allowNull)
  313. whereClause.Append (")");
  314. }
  315. if (!keyFound)
  316. throw new InvalidOperationException ("Dynamic SQL generation for the UpdateCommand is not supported against a SelectCommand that does not return any key column information.");
  317. // We're all done, so bring it on home
  318. string sql = String.Format ("{0}{1} WHERE ({2})", command, columns.ToString (), whereClause.ToString ());
  319. _updateCommand.CommandText = sql;
  320. _dbCommand = _updateCommand;
  321. return _updateCommand;
  322. }
  323. private DbParameter CreateParameter (DbCommand _dbCommand, string parameterName, DataRow schemaRow)
  324. {
  325. DbParameter parameter = _dbCommand.CreateParameter ();
  326. parameter.ParameterName = parameterName;
  327. parameter.SourceColumn = (string) schemaRow ["BaseColumnName"];
  328. parameter.Size = (int) schemaRow ["ColumnSize"];
  329. _dbCommand.Parameters.Add (parameter);
  330. return parameter;
  331. }
  332. [DefaultValue (CatalogLocation.Start)]
  333. public virtual CatalogLocation CatalogLocation {
  334. get { return _catalogLocation; }
  335. set {
  336. CheckEnumValue (typeof (CatalogLocation),
  337. (int) value);
  338. _catalogLocation = value;
  339. }
  340. }
  341. [DefaultValue (".")]
  342. public virtual string CatalogSeparator {
  343. get {
  344. if (_catalogSeparator == null || _catalogSeparator.Length == 0)
  345. return SEPARATOR_DEFAULT;
  346. return _catalogSeparator;
  347. }
  348. set { _catalogSeparator = value; }
  349. }
  350. [DefaultValue (ConflictOption.CompareAllSearchableValues)]
  351. public virtual ConflictOption ConflictOption {
  352. get { return _conflictOption; }
  353. set {
  354. CheckEnumValue (typeof (ConflictOption),
  355. (int) value);
  356. _conflictOption = value;
  357. }
  358. }
  359. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  360. [Browsable (false)]
  361. public DbDataAdapter DataAdapter {
  362. get { return _dbDataAdapter; }
  363. set { if (value != null) _dbDataAdapter = value; }
  364. }
  365. [DefaultValue ("")]
  366. public virtual string QuotePrefix {
  367. get {
  368. if (_quotePrefix == null)
  369. return string.Empty;
  370. return _quotePrefix;
  371. }
  372. set {
  373. if (IsCommandGenerated)
  374. throw new InvalidOperationException (
  375. "QuotePrefix cannot be set after " +
  376. "an Insert, Update or Delete command " +
  377. "has been generated.");
  378. _quotePrefix = value;
  379. }
  380. }
  381. [DefaultValue ("")]
  382. public virtual string QuoteSuffix {
  383. get {
  384. if (_quoteSuffix == null)
  385. return string.Empty;
  386. return _quoteSuffix;
  387. }
  388. set {
  389. if (IsCommandGenerated)
  390. throw new InvalidOperationException (
  391. "QuoteSuffix cannot be set after " +
  392. "an Insert, Update or Delete command " +
  393. "has been generated.");
  394. _quoteSuffix = value;
  395. }
  396. }
  397. [DefaultValue (".")]
  398. public virtual string SchemaSeparator {
  399. get {
  400. if (_schemaSeparator == null || _schemaSeparator.Length == 0)
  401. return SEPARATOR_DEFAULT;
  402. return _schemaSeparator;
  403. }
  404. set { _schemaSeparator = value; }
  405. }
  406. [DefaultValue (false)]
  407. public bool SetAllValues {
  408. get { return _setAllValues; }
  409. set { _setAllValues = value; }
  410. }
  411. private DbCommand SourceCommand {
  412. get {
  413. if (_dbDataAdapter != null)
  414. return _dbDataAdapter.SelectCommand;
  415. return null;
  416. }
  417. }
  418. protected abstract void ApplyParameterInfo (DbParameter parameter,
  419. DataRow row,
  420. StatementType statementType,
  421. bool whereClause);
  422. protected override void Dispose (bool disposing)
  423. {
  424. if (!_disposed) {
  425. if (disposing) {
  426. if (_insertCommand != null)
  427. _insertCommand.Dispose ();
  428. if (_deleteCommand != null)
  429. _deleteCommand.Dispose ();
  430. if (_updateCommand != null)
  431. _updateCommand.Dispose ();
  432. if (_dbSchemaTable != null)
  433. _dbSchemaTable.Dispose ();
  434. }
  435. _disposed = true;
  436. }
  437. }
  438. public DbCommand GetDeleteCommand ()
  439. {
  440. return GetDeleteCommand (false);
  441. }
  442. public DbCommand GetDeleteCommand (bool option)
  443. {
  444. BuildCache (true);
  445. if (_deleteCommand == null)
  446. return CreateDeleteCommand (option);
  447. return _deleteCommand;
  448. }
  449. public DbCommand GetInsertCommand ()
  450. {
  451. return GetInsertCommand (false);
  452. }
  453. public DbCommand GetInsertCommand (bool option)
  454. {
  455. BuildCache (true);
  456. if (_insertCommand == null)
  457. return CreateInsertCommand (option);
  458. return _insertCommand;
  459. }
  460. public DbCommand GetUpdateCommand ()
  461. {
  462. return GetUpdateCommand (false);
  463. }
  464. public DbCommand GetUpdateCommand (bool option)
  465. {
  466. BuildCache (true);
  467. if (_updateCommand == null)
  468. return CreateUpdateCommand (option);
  469. return _updateCommand;
  470. }
  471. protected virtual DbCommand InitializeCommand (DbCommand command)
  472. {
  473. if (_dbCommand == null) {
  474. _dbCommand = SourceCommand;
  475. } else {
  476. _dbCommand.CommandTimeout = 30;
  477. _dbCommand.Transaction = null;
  478. _dbCommand.CommandType = CommandType.Text;
  479. _dbCommand.UpdatedRowSource = UpdateRowSource.None;
  480. }
  481. return _dbCommand;
  482. }
  483. public virtual string QuoteIdentifier (string unquotedIdentifier)
  484. {
  485. throw new NotSupportedException ();
  486. }
  487. public virtual string UnquoteIdentifier (string quotedIdentifier)
  488. {
  489. if (quotedIdentifier == null) {
  490. throw new ArgumentNullException ("Quoted identifier parameter cannot be null");
  491. }
  492. string unquotedIdentifier = quotedIdentifier.Trim ();
  493. if (unquotedIdentifier.StartsWith (this.QuotePrefix)) {
  494. unquotedIdentifier = unquotedIdentifier.Remove (0, 1);
  495. }
  496. if (unquotedIdentifier.EndsWith (this.QuoteSuffix)) {
  497. unquotedIdentifier = unquotedIdentifier.Remove (unquotedIdentifier.Length - 1, 1);
  498. }
  499. return unquotedIdentifier;
  500. }
  501. public virtual void RefreshSchema ()
  502. {
  503. _tableName = String.Empty;
  504. _dbSchemaTable = null;
  505. _deleteCommand = null;
  506. _updateCommand = null;
  507. _insertCommand = null;
  508. }
  509. protected void RowUpdatingHandler (RowUpdatingEventArgs args)
  510. {
  511. if (args.Command != null)
  512. return;
  513. try {
  514. switch (args.StatementType) {
  515. case StatementType.Insert:
  516. args.Command = GetInsertCommand ();
  517. break;
  518. case StatementType.Update:
  519. args.Command = GetUpdateCommand ();
  520. break;
  521. case StatementType.Delete:
  522. args.Command = GetDeleteCommand ();
  523. break;
  524. }
  525. } catch (Exception e) {
  526. args.Errors = e;
  527. args.Status = UpdateStatus.ErrorsOccurred;
  528. }
  529. }
  530. protected abstract string GetParameterName (int parameterOrdinal);
  531. protected abstract string GetParameterName (String parameterName);
  532. protected abstract string GetParameterPlaceholder (int parameterOrdinal);
  533. protected abstract void SetRowUpdatingHandler (DbDataAdapter adapter);
  534. protected virtual DataTable GetSchemaTable (DbCommand cmd)
  535. {
  536. using (DbDataReader rdr = cmd.ExecuteReader ())
  537. return rdr.GetSchemaTable ();
  538. }
  539. static void CheckEnumValue (Type type, int value)
  540. {
  541. if (Enum.IsDefined (type, value))
  542. return;
  543. string typename = type.Name;
  544. string msg = string.Format (CultureInfo.CurrentCulture,
  545. "Value {0} is not valid for {1}.", value,
  546. typename);
  547. throw new ArgumentOutOfRangeException (typename, msg);
  548. }
  549. }
  550. }
  551. #endif