1 //------------------------------------------------------------------------------ 2 // <copyright file="DbCommand.cs" company="Microsoft"> 3 // Copyright (c) Microsoft Corporation. All rights reserved. 4 // </copyright> 5 // <owner current="true" primary="true">Microsoft</owner> 6 // <owner current="true" primary="false">Microsoft</owner> 7 //------------------------------------------------------------------------------ 8 9 namespace System.Data.Common { 10 11 using System; 12 using System.ComponentModel; 13 using System.Data; 14 using System.Threading.Tasks; 15 using System.Threading; 16 17 public abstract class DbCommand : Component, IDbCommand { // V1.2.3300 DbCommand()18 protected DbCommand() : base() { 19 } 20 21 [ 22 DefaultValue(""), 23 RefreshProperties(RefreshProperties.All), 24 ResCategoryAttribute(Res.DataCategory_Data), 25 ResDescriptionAttribute(Res.DbCommand_CommandText), 26 ] 27 abstract public string CommandText { 28 get; 29 set; 30 } 31 32 [ 33 ResCategoryAttribute(Res.DataCategory_Data), 34 ResDescriptionAttribute(Res.DbCommand_CommandTimeout), 35 ] 36 abstract public int CommandTimeout { 37 get; 38 set; 39 } 40 41 [ 42 DefaultValue(System.Data.CommandType.Text), 43 RefreshProperties(RefreshProperties.All), 44 ResCategoryAttribute(Res.DataCategory_Data), 45 ResDescriptionAttribute(Res.DbCommand_CommandType), 46 ] 47 abstract public CommandType CommandType { 48 get; 49 set; 50 } 51 52 [ 53 Browsable(false), 54 DefaultValue(null), 55 DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 56 ResCategoryAttribute(Res.DataCategory_Data), 57 ResDescriptionAttribute(Res.DbCommand_Connection), 58 ] 59 public DbConnection Connection { 60 get { 61 return DbConnection; 62 } 63 set { 64 DbConnection = value; 65 } 66 } 67 68 IDbConnection IDbCommand.Connection { 69 get { 70 return DbConnection; 71 } 72 set { 73 DbConnection = (DbConnection)value; 74 } 75 } 76 77 abstract protected DbConnection DbConnection { // V1.2.3300 78 get; 79 set; 80 } 81 82 abstract protected DbParameterCollection DbParameterCollection { // V1.2.3300 83 get; 84 } 85 86 abstract protected DbTransaction DbTransaction { // V1.2.3300 87 get; 88 set; 89 } 90 91 // @devnote: By default, the cmd object is visible on the design surface (i.e. VS7 Server Tray) 92 // to limit the number of components that clutter the design surface, 93 // when the DataAdapter design wizard generates the insert/update/delete commands it will 94 // set the DesignTimeVisible property to false so that cmds won't appear as individual objects 95 [ 96 DefaultValue(true), 97 DesignOnly(true), 98 Browsable(false), 99 EditorBrowsableAttribute(EditorBrowsableState.Never), 100 ] 101 public abstract bool DesignTimeVisible { 102 get; 103 set; 104 } 105 106 [ 107 Browsable(false), 108 DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 109 ResCategoryAttribute(Res.DataCategory_Data), 110 ResDescriptionAttribute(Res.DbCommand_Parameters), 111 ] 112 public DbParameterCollection Parameters { 113 get { 114 return DbParameterCollection; 115 } 116 } 117 118 IDataParameterCollection IDbCommand.Parameters { 119 get { 120 return (DbParameterCollection)DbParameterCollection; 121 } 122 } 123 124 [ 125 Browsable(false), 126 DefaultValue(null), 127 DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 128 ResDescriptionAttribute(Res.DbCommand_Transaction), 129 ] 130 public DbTransaction Transaction { 131 get { 132 return DbTransaction; 133 } 134 set { 135 DbTransaction = value; 136 } 137 } 138 139 IDbTransaction IDbCommand.Transaction { 140 get { 141 return DbTransaction; 142 } 143 set { 144 DbTransaction = (DbTransaction)value; 145 } 146 } 147 148 [ 149 DefaultValue(System.Data.UpdateRowSource.Both), 150 ResCategoryAttribute(Res.DataCategory_Update), 151 ResDescriptionAttribute(Res.DbCommand_UpdatedRowSource), 152 ] 153 abstract public UpdateRowSource UpdatedRowSource { 154 get; 155 set; 156 } 157 CancelIgnoreFailure()158 internal void CancelIgnoreFailure() { 159 // This method is used to route CancellationTokens to the Cancel method. 160 // Cancellation is a suggestion, and exceptions should be ignored 161 // rather than allowed to be unhandled, as there is no way to route 162 // them to the caller. It would be expected that the error will be 163 // observed anyway from the regular method. An example is cancelling 164 // an operation on a closed connection. 165 try 166 { 167 Cancel(); 168 } catch(Exception) { 169 } 170 } 171 Cancel()172 abstract public void Cancel(); 173 CreateParameter()174 public DbParameter CreateParameter(){ // V1.2.3300 175 return CreateDbParameter(); 176 } 177 IDbCommand.CreateParameter()178 IDbDataParameter IDbCommand.CreateParameter() { // V1.2.3300 179 return CreateDbParameter(); 180 } 181 CreateDbParameter()182 abstract protected DbParameter CreateDbParameter(); 183 ExecuteDbDataReader(CommandBehavior behavior)184 abstract protected DbDataReader ExecuteDbDataReader(CommandBehavior behavior); 185 ExecuteNonQuery()186 abstract public int ExecuteNonQuery(); 187 ExecuteReader()188 public DbDataReader ExecuteReader() { 189 return (DbDataReader)ExecuteDbDataReader(CommandBehavior.Default); 190 } 191 IDbCommand.ExecuteReader()192 IDataReader IDbCommand.ExecuteReader() { 193 return (DbDataReader)ExecuteDbDataReader(CommandBehavior.Default); 194 } 195 ExecuteReader(CommandBehavior behavior)196 public DbDataReader ExecuteReader(CommandBehavior behavior){ 197 return (DbDataReader)ExecuteDbDataReader(behavior); 198 } 199 IDbCommand.ExecuteReader(CommandBehavior behavior)200 IDataReader IDbCommand.ExecuteReader(CommandBehavior behavior) { 201 return (DbDataReader)ExecuteDbDataReader(behavior); 202 } 203 ExecuteNonQueryAsync()204 public Task<int> ExecuteNonQueryAsync() { 205 return ExecuteNonQueryAsync(CancellationToken.None); 206 } 207 ExecuteNonQueryAsync(CancellationToken cancellationToken)208 public virtual Task<int> ExecuteNonQueryAsync(CancellationToken cancellationToken) { 209 if (cancellationToken.IsCancellationRequested) { 210 return ADP.CreatedTaskWithCancellation<int>(); 211 } 212 else { 213 CancellationTokenRegistration registration = new CancellationTokenRegistration(); 214 if (cancellationToken.CanBeCanceled) { 215 registration = cancellationToken.Register(CancelIgnoreFailure); 216 } 217 218 try { 219 return Task.FromResult<int>(ExecuteNonQuery()); 220 } 221 catch (Exception e) { 222 registration.Dispose(); 223 return ADP.CreatedTaskWithException<int>(e); 224 } 225 } 226 } 227 ExecuteReaderAsync()228 public Task<DbDataReader> ExecuteReaderAsync() { 229 return ExecuteReaderAsync(CommandBehavior.Default, CancellationToken.None); 230 } 231 ExecuteReaderAsync(CancellationToken cancellationToken)232 public Task<DbDataReader> ExecuteReaderAsync(CancellationToken cancellationToken) { 233 return ExecuteReaderAsync(CommandBehavior.Default, cancellationToken); 234 } 235 ExecuteReaderAsync(CommandBehavior behavior)236 public Task<DbDataReader> ExecuteReaderAsync(CommandBehavior behavior) { 237 return ExecuteReaderAsync(behavior, CancellationToken.None); 238 } 239 ExecuteReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)240 public Task<DbDataReader> ExecuteReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken) { 241 return ExecuteDbDataReaderAsync(behavior, cancellationToken); 242 } 243 ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)244 protected virtual Task<DbDataReader> ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken) { 245 if (cancellationToken.IsCancellationRequested) { 246 return ADP.CreatedTaskWithCancellation<DbDataReader>(); 247 } 248 else { 249 CancellationTokenRegistration registration = new CancellationTokenRegistration(); 250 if (cancellationToken.CanBeCanceled) { 251 registration = cancellationToken.Register(CancelIgnoreFailure); 252 } 253 254 try { 255 return Task.FromResult<DbDataReader>(ExecuteReader(behavior)); 256 } 257 catch (Exception e) { 258 registration.Dispose(); 259 return ADP.CreatedTaskWithException<DbDataReader>(e); 260 } 261 } 262 } 263 ExecuteScalarAsync()264 public Task<object> ExecuteScalarAsync() { 265 return ExecuteScalarAsync(CancellationToken.None); 266 } 267 ExecuteScalarAsync(CancellationToken cancellationToken)268 public virtual Task<object> ExecuteScalarAsync(CancellationToken cancellationToken) { 269 if (cancellationToken.IsCancellationRequested) { 270 return ADP.CreatedTaskWithCancellation<object>(); 271 } 272 else { 273 CancellationTokenRegistration registration = new CancellationTokenRegistration(); 274 if (cancellationToken.CanBeCanceled) { 275 registration = cancellationToken.Register(CancelIgnoreFailure); 276 } 277 278 try { 279 return Task.FromResult<object>(ExecuteScalar()); 280 } 281 catch (Exception e) { 282 registration.Dispose(); 283 return ADP.CreatedTaskWithException<object>(e); 284 } 285 } 286 } 287 ExecuteScalar()288 abstract public object ExecuteScalar(); 289 Prepare()290 abstract public void Prepare(); 291 } 292 } 293