Mercurial > pub > bltoolkit
comparison Source/Data/DataProvider/OdpDataProvider.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 // Odp.Net Data Provider. | |
| 2 // http://www.oracle.com/technology/tech/windows/odpnet/index.html | |
| 3 // | |
| 4 using System; | |
| 5 using System.Collections; | |
| 6 using System.Collections.Generic; | |
| 7 using System.Data; | |
| 8 using System.Data.Common; | |
| 9 using System.Globalization; | |
| 10 using System.IO; | |
| 11 using System.Linq; | |
| 12 using System.Reflection; | |
| 13 using System.Text; | |
| 14 using System.Xml; | |
| 15 | |
| 16 using BLToolkit.Aspects; | |
| 17 using BLToolkit.Common; | |
| 18 using BLToolkit.Mapping; | |
| 19 using BLToolkit.Reflection; | |
| 20 | |
| 21 #if MANAGED | |
| 22 using Oracle.ManagedDataAccess.Client; | |
| 23 using Oracle.ManagedDataAccess.Types; | |
| 24 #else | |
| 25 using Oracle.DataAccess.Client; | |
| 26 using Oracle.DataAccess.Types; | |
| 27 #endif | |
| 28 | |
| 29 namespace BLToolkit.Data.DataProvider | |
| 30 { | |
| 31 using Sql.SqlProvider; | |
| 32 using BLToolkit.Data.Sql; | |
| 33 | |
| 34 /// <summary> | |
| 35 /// Implements access to the Data Provider for Oracle. | |
| 36 /// </summary> | |
| 37 /// <remarks> | |
| 38 /// See the <see cref="DbManager.AddDataProvider(DataProviderBase)"/> method to find an example. | |
| 39 /// </remarks> | |
| 40 /// <seealso cref="DbManager.AddDataProvider(DataProviderBase)">AddDataManager Method</seealso> | |
| 41 #if !MANAGED | |
| 42 public class OdpDataProvider : DataProviderBase | |
| 43 { | |
| 44 public OdpDataProvider() | |
| 45 { | |
| 46 MappingSchema = new OdpMappingSchema(); | |
| 47 } | |
| 48 | |
| 49 public const string NameString = DataProvider.ProviderName.Oracle; | |
| 50 | |
| 51 private const string DbTypeTableName = "Oracle.DataAccess.Client.OraDb_DbTypeTable"; | |
| 52 | |
| 53 static OdpDataProvider() | |
| 54 { | |
| 55 #else | |
| 56 public class OdpManagedDataProvider : DataProviderBase | |
| 57 { | |
| 58 public OdpManagedDataProvider() | |
| 59 { | |
| 60 MappingSchema = new OdpMappingSchema(); | |
| 61 } | |
| 62 | |
| 63 public const string NameString = DataProvider.ProviderName.OracleManaged; | |
| 64 | |
| 65 private const string DbTypeTableName = "Oracle.ManagedDataAccess.Client.OraDb_DbTypeTable"; | |
| 66 | |
| 67 static OdpManagedDataProvider() | |
| 68 { | |
| 69 #endif | |
| 70 // Fix Oracle.Net bug #1: Array types are not handled. | |
| 71 // | |
| 72 var oraDbDbTypeTableType = typeof(OracleParameter).Assembly.GetType(DbTypeTableName); | |
| 73 | |
| 74 if (null != oraDbDbTypeTableType) | |
| 75 { | |
| 76 var typeTable = (Hashtable)oraDbDbTypeTableType.InvokeMember( | |
| 77 "s_table", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.GetField, | |
| 78 null, null, Type.EmptyTypes); | |
| 79 | |
| 80 if (null != typeTable) | |
| 81 { | |
| 82 typeTable[typeof(DateTime[])] = OracleDbType.TimeStamp; | |
| 83 typeTable[typeof(Int16[])] = OracleDbType.Int16; | |
| 84 typeTable[typeof(Int32[])] = OracleDbType.Int32; | |
| 85 typeTable[typeof(Int64[])] = OracleDbType.Int64; | |
| 86 typeTable[typeof(Single[])] = OracleDbType.Single; | |
| 87 typeTable[typeof(Double[])] = OracleDbType.Double; | |
| 88 typeTable[typeof(Decimal[])] = OracleDbType.Decimal; | |
| 89 typeTable[typeof(TimeSpan[])] = OracleDbType.IntervalDS; | |
| 90 typeTable[typeof(String[])] = OracleDbType.Varchar2; | |
| 91 typeTable[typeof(OracleBFile[])] = OracleDbType.BFile; | |
| 92 typeTable[typeof(OracleBinary[])] = OracleDbType.Raw; | |
| 93 typeTable[typeof(OracleBlob[])] = OracleDbType.Blob; | |
| 94 typeTable[typeof(OracleClob[])] = OracleDbType.Clob; | |
| 95 typeTable[typeof(OracleDate[])] = OracleDbType.Date; | |
| 96 typeTable[typeof(OracleDecimal[])] = OracleDbType.Decimal; | |
| 97 typeTable[typeof(OracleIntervalDS[])] = OracleDbType.IntervalDS; | |
| 98 typeTable[typeof(OracleIntervalYM[])] = OracleDbType.IntervalYM; | |
| 99 typeTable[typeof(OracleRefCursor[])] = OracleDbType.RefCursor; | |
| 100 typeTable[typeof(OracleString[])] = OracleDbType.Varchar2; | |
| 101 typeTable[typeof(OracleTimeStamp[])] = OracleDbType.TimeStamp; | |
| 102 typeTable[typeof(OracleTimeStampLTZ[])]= OracleDbType.TimeStampLTZ; | |
| 103 typeTable[typeof(OracleTimeStampTZ[])] = OracleDbType.TimeStampTZ; | |
| 104 #if !MANAGED | |
| 105 typeTable[typeof(OracleXmlType[])] = OracleDbType.XmlType; | |
| 106 #endif | |
| 107 | |
| 108 typeTable[typeof(Boolean)] = OracleDbType.Byte; | |
| 109 typeTable[typeof(Guid)] = OracleDbType.Raw; | |
| 110 typeTable[typeof(SByte)] = OracleDbType.Decimal; | |
| 111 typeTable[typeof(UInt16)] = OracleDbType.Decimal; | |
| 112 typeTable[typeof(UInt32)] = OracleDbType.Decimal; | |
| 113 typeTable[typeof(UInt64)] = OracleDbType.Decimal; | |
| 114 | |
| 115 typeTable[typeof(Boolean[])] = OracleDbType.Byte; | |
| 116 typeTable[typeof(Guid[])] = OracleDbType.Raw; | |
| 117 typeTable[typeof(SByte[])] = OracleDbType.Decimal; | |
| 118 typeTable[typeof(UInt16[])] = OracleDbType.Decimal; | |
| 119 typeTable[typeof(UInt32[])] = OracleDbType.Decimal; | |
| 120 typeTable[typeof(UInt64[])] = OracleDbType.Decimal; | |
| 121 | |
| 122 typeTable[typeof(Boolean?)] = OracleDbType.Byte; | |
| 123 typeTable[typeof(Guid?)] = OracleDbType.Raw; | |
| 124 typeTable[typeof(SByte?)] = OracleDbType.Decimal; | |
| 125 typeTable[typeof(UInt16?)] = OracleDbType.Decimal; | |
| 126 typeTable[typeof(UInt32?)] = OracleDbType.Decimal; | |
| 127 typeTable[typeof(UInt64?)] = OracleDbType.Decimal; | |
| 128 typeTable[typeof(DateTime?[])] = OracleDbType.TimeStamp; | |
| 129 typeTable[typeof(Int16?[])] = OracleDbType.Int16; | |
| 130 typeTable[typeof(Int32?[])] = OracleDbType.Int32; | |
| 131 typeTable[typeof(Int64?[])] = OracleDbType.Int64; | |
| 132 typeTable[typeof(Single?[])] = OracleDbType.Single; | |
| 133 typeTable[typeof(Double?[])] = OracleDbType.Double; | |
| 134 typeTable[typeof(Decimal?[])] = OracleDbType.Decimal; | |
| 135 typeTable[typeof(TimeSpan?[])] = OracleDbType.IntervalDS; | |
| 136 typeTable[typeof(Boolean?[])] = OracleDbType.Byte; | |
| 137 typeTable[typeof(Guid?[])] = OracleDbType.Raw; | |
| 138 typeTable[typeof(SByte?[])] = OracleDbType.Decimal; | |
| 139 typeTable[typeof(UInt16?[])] = OracleDbType.Decimal; | |
| 140 typeTable[typeof(UInt32?[])] = OracleDbType.Decimal; | |
| 141 typeTable[typeof(UInt64?[])] = OracleDbType.Decimal; | |
| 142 | |
| 143 typeTable[typeof(XmlReader)] = OracleDbType.XmlType; | |
| 144 typeTable[typeof(XmlDocument)] = OracleDbType.XmlType; | |
| 145 typeTable[typeof(MemoryStream)] = OracleDbType.Blob; | |
| 146 typeTable[typeof(XmlReader[])] = OracleDbType.XmlType; | |
| 147 typeTable[typeof(XmlDocument[])] = OracleDbType.XmlType; | |
| 148 typeTable[typeof(MemoryStream[])] = OracleDbType.Blob; | |
| 149 } | |
| 150 } | |
| 151 } | |
| 152 | |
| 153 /// <summary> | |
| 154 /// Creates the database connection object. | |
| 155 /// </summary> | |
| 156 /// <remarks> | |
| 157 /// See the <see cref="DbManager.AddDataProvider(DataProviderBase)"/> method to find an example. | |
| 158 /// </remarks> | |
| 159 /// <seealso cref="DbManager.AddDataProvider(DataProviderBase)">AddDataManager Method</seealso> | |
| 160 /// <returns>The database connection object.</returns> | |
| 161 public override IDbConnection CreateConnectionObject() | |
| 162 { | |
| 163 return new OracleConnection(); | |
| 164 } | |
| 165 | |
| 166 public override IDbCommand CreateCommandObject(IDbConnection connection) | |
| 167 { | |
| 168 var oraConnection = connection as OracleConnection; | |
| 169 | |
| 170 if (null != oraConnection) | |
| 171 { | |
| 172 var oraCommand = oraConnection.CreateCommand(); | |
| 173 | |
| 174 // Fix Oracle.Net bug #2: Empty arrays can not be sent to the server. | |
| 175 // | |
| 176 oraCommand.BindByName = true; | |
| 177 | |
| 178 return oraCommand; | |
| 179 } | |
| 180 | |
| 181 return base.CreateCommandObject(connection); | |
| 182 } | |
| 183 | |
| 184 public override void SetParameterValue(IDbDataParameter parameter, object value) | |
| 185 { | |
| 186 base.SetParameterValue(parameter, value); | |
| 187 | |
| 188 // strings and byte arrays larger than 4000 bytes may be handled improperly | |
| 189 if (parameter is OracleParameterWrap) | |
| 190 { | |
| 191 const int ThresholdSize = 4000; | |
| 192 if (value is string && Encoding.UTF8.GetBytes((string)value).Length > ThresholdSize) | |
| 193 { | |
| 194 ((OracleParameterWrap)parameter).OracleParameter.OracleDbType = OracleDbType.Clob; | |
| 195 } | |
| 196 else if (value is byte[] && ((byte[])value).Length > ThresholdSize) | |
| 197 { | |
| 198 ((OracleParameterWrap)parameter).OracleParameter.OracleDbType = OracleDbType.Blob; | |
| 199 } | |
| 200 } | |
| 201 } | |
| 202 | |
| 203 public override IDbDataParameter CloneParameter(IDbDataParameter parameter) | |
| 204 { | |
| 205 var oraParameter = (parameter is OracleParameterWrap)? | |
| 206 (parameter as OracleParameterWrap).OracleParameter: parameter as OracleParameter; | |
| 207 | |
| 208 if (null != oraParameter) | |
| 209 { | |
| 210 var oraParameterClone = (OracleParameter)oraParameter.Clone(); | |
| 211 | |
| 212 // Fix Oracle.Net bug #3: CollectionType property is not cloned. | |
| 213 // | |
| 214 oraParameterClone.CollectionType = oraParameter.CollectionType; | |
| 215 | |
| 216 // Fix Oracle.Net bug #8423178 | |
| 217 // See http://forums.oracle.com/forums/thread.jspa?threadID=975902&tstart=0 | |
| 218 // | |
| 219 if (oraParameterClone.OracleDbType == OracleDbType.RefCursor) | |
| 220 { | |
| 221 // Set OracleDbType to itself to reset m_bSetDbType and m_bOracleDbTypeExSet | |
| 222 // | |
| 223 oraParameterClone.OracleDbType = OracleDbType.RefCursor; | |
| 224 } | |
| 225 | |
| 226 return OracleParameterWrap.CreateInstance(oraParameterClone); | |
| 227 } | |
| 228 | |
| 229 return base.CloneParameter(parameter); | |
| 230 } | |
| 231 | |
| 232 public override void SetUserDefinedType(IDbDataParameter parameter, string typeName) | |
| 233 { | |
| 234 var oraParameter = (parameter is OracleParameterWrap) ? | |
| 235 (parameter as OracleParameterWrap).OracleParameter : parameter as OracleParameter; | |
| 236 | |
| 237 if (oraParameter == null) | |
| 238 throw new ArgumentException("OracleParameter expected.", "parameter"); | |
| 239 | |
| 240 oraParameter.UdtTypeName = typeName; | |
| 241 } | |
| 242 | |
| 243 /// <summary> | |
| 244 /// Creates the data adapter object. | |
| 245 /// </summary> | |
| 246 /// <remarks> | |
| 247 /// See the <see cref="DbManager.AddDataProvider(DataProviderBase)"/> method to find an example. | |
| 248 /// </remarks> | |
| 249 /// <seealso cref="DbManager.AddDataProvider(DataProviderBase)">AddDataManager Method</seealso> | |
| 250 /// <returns>A data adapter object.</returns> | |
| 251 public override DbDataAdapter CreateDataAdapterObject() | |
| 252 { | |
| 253 return new OracleDataAdapter(); | |
| 254 } | |
| 255 | |
| 256 /// <summary> | |
| 257 /// Populates the specified IDbCommand object's Parameters collection with | |
| 258 /// parameter information for the stored procedure specified in the IDbCommand. | |
| 259 /// </summary> | |
| 260 /// <remarks> | |
| 261 /// See the <see cref="DbManager.AddDataProvider(DataProviderBase)"/> method to find an example. | |
| 262 /// </remarks> | |
| 263 /// <seealso cref="DbManager.AddDataProvider(DataProviderBase)">AddDataManager Method</seealso> | |
| 264 /// <param name="command">The IDbCommand referencing the stored procedure for which the parameter | |
| 265 /// information is to be derived. The derived parameters will be populated into | |
| 266 /// the Parameters of this command.</param> | |
| 267 public override bool DeriveParameters(IDbCommand command) | |
| 268 { | |
| 269 var oraCommand = command as OracleCommand; | |
| 270 | |
| 271 if (null != oraCommand) | |
| 272 { | |
| 273 try | |
| 274 { | |
| 275 OracleCommandBuilder.DeriveParameters(oraCommand); | |
| 276 } | |
| 277 catch (Exception ex) | |
| 278 { | |
| 279 // Make Oracle less laconic. | |
| 280 // | |
| 281 throw new DataException(string.Format("{0}\nCommandText: {1}", ex.Message, oraCommand.CommandText), ex); | |
| 282 } | |
| 283 | |
| 284 return true; | |
| 285 } | |
| 286 | |
| 287 return false; | |
| 288 } | |
| 289 | |
| 290 /// <summary> | |
| 291 /// Open an <see cref="IDataReader"/> into the given <see cref="OracleRefCursor"/> object | |
| 292 /// </summary> | |
| 293 /// <param name="refCursor">an <see cref="OracleRefCursor"/> to perform GetDataReader() on</param> | |
| 294 /// <returns>The <see cref="IDataReader"/> into the returned by GetDataReader()</returns> | |
| 295 public override IDataReader GetRefCursorDataReader(object refCursor) | |
| 296 { | |
| 297 var oracleRefCursor = refCursor as OracleRefCursor; | |
| 298 | |
| 299 if (oracleRefCursor == null) | |
| 300 throw new ArgumentException("Argument must be of type 'OracleRefCursor'", "refCursor"); | |
| 301 | |
| 302 return oracleRefCursor.GetDataReader(); | |
| 303 } | |
| 304 | |
| 305 public override object Convert(object value, ConvertType convertType) | |
| 306 { | |
| 307 switch (convertType) | |
| 308 { | |
| 309 case ConvertType.NameToCommandParameter: | |
| 310 case ConvertType.NameToSprocParameter: | |
| 311 return ParameterPrefix == null? value: ParameterPrefix + value; | |
| 312 | |
| 313 case ConvertType.SprocParameterToName: | |
| 314 var name = (string)value; | |
| 315 | |
| 316 if (name.Length > 0) | |
| 317 { | |
| 318 if (name[0] == ':') | |
| 319 return name.Substring(1); | |
| 320 | |
| 321 if (ParameterPrefix != null && | |
| 322 name.ToUpper(CultureInfo.InvariantCulture).StartsWith(ParameterPrefix)) | |
| 323 { | |
| 324 return name.Substring(ParameterPrefix.Length); | |
| 325 } | |
| 326 } | |
| 327 | |
| 328 break; | |
| 329 | |
| 330 case ConvertType.ExceptionToErrorNumber: | |
| 331 if (value is OracleException) | |
| 332 return ((OracleException)value).Number; | |
| 333 break; | |
| 334 } | |
| 335 | |
| 336 return SqlProvider.Convert(value, convertType); | |
| 337 } | |
| 338 | |
| 339 public override void PrepareCommand(ref CommandType commandType, ref string commandText, ref IDbDataParameter[] commandParameters) | |
| 340 { | |
| 341 base.PrepareCommand(ref commandType, ref commandText, ref commandParameters); | |
| 342 | |
| 343 if (commandType == CommandType.Text) | |
| 344 { | |
| 345 // Fix Oracle bug #11 '\r' is not a valid character! | |
| 346 // | |
| 347 commandText = commandText.Replace('\r', ' '); | |
| 348 } | |
| 349 } | |
| 350 | |
| 351 public override void AttachParameter(IDbCommand command, IDbDataParameter parameter) | |
| 352 { | |
| 353 var oraParameter = (parameter is OracleParameterWrap)? | |
| 354 (parameter as OracleParameterWrap).OracleParameter: parameter as OracleParameter; | |
| 355 | |
| 356 if (null != oraParameter) | |
| 357 { | |
| 358 if (oraParameter.CollectionType == OracleCollectionType.PLSQLAssociativeArray) | |
| 359 { | |
| 360 if (oraParameter.Direction == ParameterDirection.Input | |
| 361 || oraParameter.Direction == ParameterDirection.InputOutput) | |
| 362 { | |
| 363 var ar = oraParameter.Value as Array; | |
| 364 | |
| 365 if (null != ar && !(ar is byte[] || ar is char[])) | |
| 366 { | |
| 367 oraParameter.Size = ar.Length; | |
| 368 | |
| 369 if (oraParameter.DbType == DbType.String | |
| 370 && oraParameter.Direction == ParameterDirection.InputOutput) | |
| 371 { | |
| 372 var arrayBindSize = new int[oraParameter.Size]; | |
| 373 | |
| 374 for (var i = 0; i < oraParameter.Size; ++i) | |
| 375 { | |
| 376 arrayBindSize[i] = 1024; | |
| 377 } | |
| 378 | |
| 379 oraParameter.ArrayBindSize = arrayBindSize; | |
| 380 } | |
| 381 } | |
| 382 | |
| 383 if (oraParameter.Size == 0) | |
| 384 { | |
| 385 // Skip this parameter. | |
| 386 // Fix Oracle.Net bug #2: Empty arrays can not be sent to the server. | |
| 387 // | |
| 388 return; | |
| 389 } | |
| 390 | |
| 391 if (oraParameter.Value is Stream[]) | |
| 392 { | |
| 393 var streams = (Stream[]) oraParameter.Value; | |
| 394 | |
| 395 for (var i = 0; i < oraParameter.Size; ++i) | |
| 396 { | |
| 397 if (streams[i] is OracleBFile || streams[i] is OracleBlob || streams[i] is OracleClob | |
| 398 #if !MANAGED | |
| 399 || streams[i] is OracleXmlStream | |
| 400 #endif | |
| 401 ) | |
| 402 { | |
| 403 // Known Oracle type. | |
| 404 // | |
| 405 continue; | |
| 406 } | |
| 407 | |
| 408 streams[i] = CopyStream(streams[i], (OracleCommand)command); | |
| 409 } | |
| 410 } | |
| 411 else if (oraParameter.Value is XmlDocument[]) | |
| 412 { | |
| 413 var xmlDocuments = (XmlDocument[]) oraParameter.Value; | |
| 414 var values = new object[oraParameter.Size]; | |
| 415 | |
| 416 switch (oraParameter.OracleDbType) | |
| 417 { | |
| 418 case OracleDbType.XmlType: | |
| 419 #if !MANAGED | |
| 420 for (var i = 0; i < oraParameter.Size; ++i) | |
| 421 { | |
| 422 values[i] = xmlDocuments[i].DocumentElement == null? | |
| 423 (object) DBNull.Value: | |
| 424 new OracleXmlType((OracleConnection)command.Connection, xmlDocuments[i]); | |
| 425 } | |
| 426 | |
| 427 oraParameter.Value = values; | |
| 428 break; | |
| 429 #else | |
| 430 throw new NotSupportedException(); | |
| 431 #endif | |
| 432 // Fix Oracle.Net bug #9: XmlDocument.ToString() returns System.Xml.XmlDocument, | |
| 433 // so m_value.ToString() is not enought. | |
| 434 // | |
| 435 case OracleDbType.Clob: | |
| 436 case OracleDbType.NClob: | |
| 437 case OracleDbType.Varchar2: | |
| 438 case OracleDbType.NVarchar2: | |
| 439 case OracleDbType.Char: | |
| 440 case OracleDbType.NChar: | |
| 441 for (var i = 0; i < oraParameter.Size; ++i) | |
| 442 { | |
| 443 values[i] = xmlDocuments[i].DocumentElement == null? | |
| 444 (object) DBNull.Value: | |
| 445 xmlDocuments[i].InnerXml; | |
| 446 } | |
| 447 | |
| 448 oraParameter.Value = values; | |
| 449 | |
| 450 break; | |
| 451 | |
| 452 // Or convert to bytes if need. | |
| 453 // | |
| 454 case OracleDbType.Blob: | |
| 455 case OracleDbType.BFile: | |
| 456 case OracleDbType.Raw: | |
| 457 case OracleDbType.Long: | |
| 458 case OracleDbType.LongRaw: | |
| 459 for (var i = 0; i < oraParameter.Size; ++i) | |
| 460 { | |
| 461 if (xmlDocuments[i].DocumentElement == null) | |
| 462 values[i] = DBNull.Value; | |
| 463 else | |
| 464 using (var s = new MemoryStream()) | |
| 465 { | |
| 466 xmlDocuments[i].Save(s); | |
| 467 values[i] = s.GetBuffer(); | |
| 468 } | |
| 469 } | |
| 470 | |
| 471 oraParameter.Value = values; | |
| 472 | |
| 473 break; | |
| 474 } | |
| 475 } | |
| 476 } | |
| 477 else if (oraParameter.Direction == ParameterDirection.Output) | |
| 478 { | |
| 479 // Fix Oracle.Net bug #4: ArrayBindSize must be explicitly specified. | |
| 480 // | |
| 481 if (oraParameter.DbType == DbType.String) | |
| 482 { | |
| 483 oraParameter.Size = 1024; | |
| 484 var arrayBindSize = new int[oraParameter.Size]; | |
| 485 for (var i = 0; i < oraParameter.Size; ++i) | |
| 486 { | |
| 487 arrayBindSize[i] = 1024; | |
| 488 } | |
| 489 | |
| 490 oraParameter.ArrayBindSize = arrayBindSize; | |
| 491 } | |
| 492 else | |
| 493 { | |
| 494 oraParameter.Size = 32767; | |
| 495 } | |
| 496 } | |
| 497 } | |
| 498 else if (oraParameter.Value is Stream) | |
| 499 { | |
| 500 var stream = (Stream) oraParameter.Value; | |
| 501 | |
| 502 if (!(stream is OracleBFile) && !(stream is OracleBlob) && | |
| 503 !(stream is OracleClob) | |
| 504 #if !MANAGED | |
| 505 && !(stream is OracleXmlStream) | |
| 506 #endif | |
| 507 ) | |
| 508 { | |
| 509 oraParameter.Value = CopyStream(stream, (OracleCommand)command); | |
| 510 } | |
| 511 } | |
| 512 else if (oraParameter.Value is Byte[]) | |
| 513 { | |
| 514 var bytes = (Byte[]) oraParameter.Value; | |
| 515 | |
| 516 if (bytes.Length > 32000) | |
| 517 { | |
| 518 oraParameter.Value = CopyStream(bytes, (OracleCommand)command); | |
| 519 } | |
| 520 } | |
| 521 else if (oraParameter.Value is XmlDocument) | |
| 522 { | |
| 523 var xmlDocument = (XmlDocument)oraParameter.Value; | |
| 524 if (xmlDocument.DocumentElement == null) | |
| 525 oraParameter.Value = DBNull.Value; | |
| 526 else | |
| 527 { | |
| 528 | |
| 529 switch (oraParameter.OracleDbType) | |
| 530 { | |
| 531 case OracleDbType.XmlType: | |
| 532 #if !MANAGED | |
| 533 oraParameter.Value = new OracleXmlType((OracleConnection)command.Connection, xmlDocument); | |
| 534 break; | |
| 535 #else | |
| 536 throw new NotSupportedException(); | |
| 537 #endif | |
| 538 | |
| 539 // Fix Oracle.Net bug #9: XmlDocument.ToString() returns System.Xml.XmlDocument, | |
| 540 // so m_value.ToString() is not enought. | |
| 541 // | |
| 542 case OracleDbType.Clob: | |
| 543 case OracleDbType.NClob: | |
| 544 case OracleDbType.Varchar2: | |
| 545 case OracleDbType.NVarchar2: | |
| 546 case OracleDbType.Char: | |
| 547 case OracleDbType.NChar: | |
| 548 using (TextWriter w = new StringWriter()) | |
| 549 { | |
| 550 xmlDocument.Save(w); | |
| 551 oraParameter.Value = w.ToString(); | |
| 552 } | |
| 553 break; | |
| 554 | |
| 555 // Or convert to bytes if need. | |
| 556 // | |
| 557 case OracleDbType.Blob: | |
| 558 case OracleDbType.BFile: | |
| 559 case OracleDbType.Raw: | |
| 560 case OracleDbType.Long: | |
| 561 case OracleDbType.LongRaw: | |
| 562 using (var s = new MemoryStream()) | |
| 563 { | |
| 564 xmlDocument.Save(s); | |
| 565 oraParameter.Value = s.GetBuffer(); | |
| 566 } | |
| 567 break; | |
| 568 } | |
| 569 } | |
| 570 } | |
| 571 | |
| 572 parameter = oraParameter; | |
| 573 } | |
| 574 | |
| 575 base.AttachParameter(command, parameter); | |
| 576 } | |
| 577 | |
| 578 private static Stream CopyStream(Stream stream, OracleCommand cmd) | |
| 579 { | |
| 580 return CopyStream(Common.Convert.ToByteArray(stream), cmd); | |
| 581 } | |
| 582 | |
| 583 private static Stream CopyStream(Byte[] bytes, OracleCommand cmd) | |
| 584 { | |
| 585 var ret = new OracleBlob(cmd.Connection); | |
| 586 ret.Write(bytes, 0, bytes.Length); | |
| 587 return ret; | |
| 588 } | |
| 589 | |
| 590 public override bool IsValueParameter(IDbDataParameter parameter) | |
| 591 { | |
| 592 var oraParameter = (parameter is OracleParameterWrap)? | |
| 593 (parameter as OracleParameterWrap).OracleParameter: parameter as OracleParameter; | |
| 594 | |
| 595 if (null != oraParameter) | |
| 596 { | |
| 597 if (oraParameter.OracleDbType == OracleDbType.RefCursor | |
| 598 && oraParameter.Direction == ParameterDirection.Output) | |
| 599 { | |
| 600 // Ignore out ref cursors, while out parameters of other types are o.k. | |
| 601 return false; | |
| 602 } | |
| 603 } | |
| 604 | |
| 605 return base.IsValueParameter(parameter); | |
| 606 } | |
| 607 | |
| 608 public override IDbDataParameter CreateParameterObject(IDbCommand command) | |
| 609 { | |
| 610 var parameter = base.CreateParameterObject(command); | |
| 611 | |
| 612 if (parameter is OracleParameter) | |
| 613 parameter = OracleParameterWrap.CreateInstance(parameter as OracleParameter); | |
| 614 | |
| 615 return parameter; | |
| 616 } | |
| 617 | |
| 618 public override IDbDataParameter GetParameter(IDbCommand command, NameOrIndexParameter nameOrIndex) | |
| 619 { | |
| 620 var parameter = base.GetParameter(command, nameOrIndex); | |
| 621 | |
| 622 if (parameter is OracleParameter) | |
| 623 parameter = OracleParameterWrap.CreateInstance(parameter as OracleParameter); | |
| 624 | |
| 625 return parameter; | |
| 626 } | |
| 627 | |
| 628 /// <summary> | |
| 629 /// Returns connection type. | |
| 630 /// </summary> | |
| 631 /// <remarks> | |
| 632 /// See the <see cref="DbManager.AddDataProvider(DataProviderBase)"/> method to find an example. | |
| 633 /// </remarks> | |
| 634 /// <seealso cref="DbManager.AddDataProvider(DataProviderBase)">AddDataManager Method</seealso> | |
| 635 /// <value>An instance of the <see cref="Type"/> class.</value> | |
| 636 public override Type ConnectionType | |
| 637 { | |
| 638 get { return typeof(OracleConnection); } | |
| 639 } | |
| 640 | |
| 641 /// <summary> | |
| 642 /// Returns the data provider name. | |
| 643 /// </summary> | |
| 644 /// <remarks> | |
| 645 /// See the <see cref="DbManager.AddDataProvider(DataProviderBase)"/> method to find an example. | |
| 646 /// </remarks> | |
| 647 /// <seealso cref="DbManager.AddDataProvider(DataProviderBase)">AddDataProvider Method</seealso> | |
| 648 /// <value>Data provider name.</value> | |
| 649 public override string Name | |
| 650 { | |
| 651 get { return NameString; } | |
| 652 } | |
| 653 | |
| 654 public override int MaxBatchSize | |
| 655 { | |
| 656 get { return 0; } | |
| 657 } | |
| 658 | |
| 659 public override int ExecuteArray(IDbCommand command, int iterations) | |
| 660 { | |
| 661 var cmd = (OracleCommand)command; | |
| 662 var oracleParameters = cmd.Parameters.OfType<OracleParameter>().ToArray(); | |
| 663 var oldCollectionTypes = oracleParameters.Select(p => p.CollectionType).ToArray(); | |
| 664 | |
| 665 try | |
| 666 { | |
| 667 foreach (var p in oracleParameters) | |
| 668 { | |
| 669 p.CollectionType = OracleCollectionType.None; | |
| 670 } | |
| 671 | |
| 672 cmd.ArrayBindCount = iterations; | |
| 673 return cmd.ExecuteNonQuery(); | |
| 674 } | |
| 675 finally | |
| 676 { | |
| 677 foreach (var p in oracleParameters.Zip(oldCollectionTypes, (p, t) => new { Param = p, CollectionType = t })) | |
| 678 { | |
| 679 p.Param.CollectionType = p.CollectionType; | |
| 680 } | |
| 681 | |
| 682 cmd.ArrayBindCount = 0; | |
| 683 } | |
| 684 } | |
| 685 | |
| 686 public override ISqlProvider CreateSqlProvider() | |
| 687 { | |
| 688 return new OracleSqlProvider(); | |
| 689 } | |
| 690 | |
| 691 public override IDataReader GetDataReader(MappingSchema schema, IDataReader dataReader) | |
| 692 { | |
| 693 return dataReader is OracleDataReader ? | |
| 694 new OracleDataReaderEx((OracleDataReader)dataReader) : | |
| 695 base.GetDataReader(schema, dataReader); | |
| 696 } | |
| 697 | |
| 698 class OracleDataReaderEx: DataReaderEx<OracleDataReader> | |
| 699 { | |
| 700 public OracleDataReaderEx(OracleDataReader rd) | |
| 701 : base(rd) | |
| 702 { | |
| 703 } | |
| 704 | |
| 705 public override DateTimeOffset GetDateTimeOffset(int i) | |
| 706 { | |
| 707 var ts = DataReader.GetOracleTimeStampTZ(i); | |
| 708 return new DateTimeOffset(ts.Value, ts.GetTimeZoneOffset()); | |
| 709 } | |
| 710 } | |
| 711 | |
| 712 private string _parameterPrefix = "P"; | |
| 713 public string ParameterPrefix | |
| 714 { | |
| 715 get { return _parameterPrefix; } | |
| 716 set | |
| 717 { | |
| 718 _parameterPrefix = string.IsNullOrEmpty(value)? null: | |
| 719 value.ToUpper(CultureInfo.InvariantCulture); | |
| 720 } | |
| 721 } | |
| 722 | |
| 723 /// <summary> | |
| 724 /// One time initialization from a configuration file. | |
| 725 /// </summary> | |
| 726 /// <param name="attributes">Provider specific attributes.</param> | |
| 727 public override void Configure(System.Collections.Specialized.NameValueCollection attributes) | |
| 728 { | |
| 729 var val = attributes["ParameterPrefix"]; | |
| 730 if (val != null) | |
| 731 ParameterPrefix = val; | |
| 732 | |
| 733 base.Configure(attributes); | |
| 734 } | |
| 735 | |
| 736 #region Inner types | |
| 737 | |
| 738 public class OdpMappingSchema : MappingSchema | |
| 739 { | |
| 740 public override DataReaderMapper CreateDataReaderMapper(IDataReader dataReader) | |
| 741 { | |
| 742 return new OracleDataReaderMapper(this, dataReader); | |
| 743 } | |
| 744 | |
| 745 public override DataReaderMapper CreateDataReaderMapper( | |
| 746 IDataReader dataReader, | |
| 747 NameOrIndexParameter nip) | |
| 748 { | |
| 749 return new OracleScalarDataReaderMapper(this, dataReader, nip); | |
| 750 } | |
| 751 | |
| 752 public override Reflection.Extension.ExtensionList Extensions | |
| 753 { | |
| 754 get { return Map.DefaultSchema.Extensions; } | |
| 755 set { Map.DefaultSchema.Extensions = value; } | |
| 756 } | |
| 757 | |
| 758 #region Convert | |
| 759 | |
| 760 #region Primitive Types | |
| 761 | |
| 762 [CLSCompliant(false)] | |
| 763 public override SByte ConvertToSByte(object value) | |
| 764 { | |
| 765 if (value is OracleDecimal) | |
| 766 { | |
| 767 var oraDecimal = (OracleDecimal)value; | |
| 768 return oraDecimal.IsNull? DefaultSByteNullValue: (SByte)oraDecimal.Value; | |
| 769 } | |
| 770 | |
| 771 return base.ConvertToSByte(value); | |
| 772 } | |
| 773 | |
| 774 public override Int16 ConvertToInt16(object value) | |
| 775 { | |
| 776 if (value is OracleDecimal) | |
| 777 { | |
| 778 var oraDecimal = (OracleDecimal)value; | |
| 779 return oraDecimal.IsNull? DefaultInt16NullValue: oraDecimal.ToInt16(); | |
| 780 } | |
| 781 | |
| 782 return base.ConvertToInt16(value); | |
| 783 } | |
| 784 | |
| 785 public override Int32 ConvertToInt32(object value) | |
| 786 { | |
| 787 if (value is OracleDecimal) | |
| 788 { | |
| 789 var oraDecimal = (OracleDecimal)value; | |
| 790 return oraDecimal.IsNull? DefaultInt32NullValue: oraDecimal.ToInt32(); | |
| 791 } | |
| 792 | |
| 793 return base.ConvertToInt32(value); | |
| 794 } | |
| 795 | |
| 796 public override Int64 ConvertToInt64(object value) | |
| 797 { | |
| 798 if (value is OracleDecimal) | |
| 799 { | |
| 800 var oraDecimal = (OracleDecimal)value; | |
| 801 return oraDecimal.IsNull? DefaultInt64NullValue: oraDecimal.ToInt64(); | |
| 802 } | |
| 803 | |
| 804 return base.ConvertToInt64(value); | |
| 805 } | |
| 806 | |
| 807 public override Byte ConvertToByte(object value) | |
| 808 { | |
| 809 if (value is OracleDecimal) | |
| 810 { | |
| 811 var oraDecimal = (OracleDecimal)value; | |
| 812 return oraDecimal.IsNull? DefaultByteNullValue: oraDecimal.ToByte(); | |
| 813 } | |
| 814 | |
| 815 return base.ConvertToByte(value); | |
| 816 } | |
| 817 | |
| 818 [CLSCompliant(false)] | |
| 819 public override UInt16 ConvertToUInt16(object value) | |
| 820 { | |
| 821 if (value is OracleDecimal) | |
| 822 { | |
| 823 var oraDecimal = (OracleDecimal)value; | |
| 824 return oraDecimal.IsNull? DefaultUInt16NullValue: (UInt16)oraDecimal.Value; | |
| 825 } | |
| 826 | |
| 827 return base.ConvertToUInt16(value); | |
| 828 } | |
| 829 | |
| 830 [CLSCompliant(false)] | |
| 831 public override UInt32 ConvertToUInt32(object value) | |
| 832 { | |
| 833 if (value is OracleDecimal) | |
| 834 { | |
| 835 var oraDecimal = (OracleDecimal)value; | |
| 836 return oraDecimal.IsNull? DefaultUInt32NullValue: (UInt32)oraDecimal.Value; | |
| 837 } | |
| 838 | |
| 839 return base.ConvertToUInt32(value); | |
| 840 } | |
| 841 | |
| 842 [CLSCompliant(false)] | |
| 843 public override UInt64 ConvertToUInt64(object value) | |
| 844 { | |
| 845 if (value is OracleDecimal) | |
| 846 { | |
| 847 var oraDecimal = (OracleDecimal)value; | |
| 848 return oraDecimal.IsNull? DefaultUInt64NullValue: (UInt64)oraDecimal.Value; | |
| 849 } | |
| 850 | |
| 851 return base.ConvertToUInt64(value); | |
| 852 } | |
| 853 | |
| 854 public override Single ConvertToSingle(object value) | |
| 855 { | |
| 856 if (value is OracleDecimal) | |
| 857 { | |
| 858 var oraDecimal = (OracleDecimal)value; | |
| 859 return oraDecimal.IsNull? DefaultSingleNullValue: oraDecimal.ToSingle(); | |
| 860 } | |
| 861 | |
| 862 return base.ConvertToSingle(value); | |
| 863 } | |
| 864 | |
| 865 public override Double ConvertToDouble(object value) | |
| 866 { | |
| 867 if (value is OracleDecimal) | |
| 868 { | |
| 869 var oraDecimal = (OracleDecimal)value; | |
| 870 return oraDecimal.IsNull? DefaultDoubleNullValue: oraDecimal.ToDouble(); | |
| 871 } | |
| 872 | |
| 873 return base.ConvertToDouble(value); | |
| 874 } | |
| 875 | |
| 876 public override Boolean ConvertToBoolean(object value) | |
| 877 { | |
| 878 if (value is OracleDecimal) | |
| 879 { | |
| 880 var oraDecimal = (OracleDecimal)value; | |
| 881 return oraDecimal.IsNull? DefaultBooleanNullValue: (oraDecimal.Value != 0); | |
| 882 } | |
| 883 | |
| 884 return base.ConvertToBoolean(value); | |
| 885 } | |
| 886 | |
| 887 public override DateTime ConvertToDateTime(object value) | |
| 888 { | |
| 889 if (value is OracleDate) | |
| 890 { | |
| 891 var oraDate = (OracleDate)value; | |
| 892 return oraDate.IsNull? DefaultDateTimeNullValue: oraDate.Value; | |
| 893 } | |
| 894 | |
| 895 return base.ConvertToDateTime(value); | |
| 896 } | |
| 897 | |
| 898 public override Decimal ConvertToDecimal(object value) | |
| 899 { | |
| 900 if (value is OracleDecimal) | |
| 901 { | |
| 902 var oraDecimal = (OracleDecimal)value; | |
| 903 return oraDecimal.IsNull? DefaultDecimalNullValue: oraDecimal.Value; | |
| 904 } | |
| 905 | |
| 906 return base.ConvertToDecimal(value); | |
| 907 } | |
| 908 | |
| 909 public override Guid ConvertToGuid(object value) | |
| 910 { | |
| 911 if (value is OracleString) | |
| 912 { | |
| 913 var oraString = (OracleString)value; | |
| 914 return oraString.IsNull? DefaultGuidNullValue: new Guid(oraString.Value); | |
| 915 } | |
| 916 | |
| 917 if (value is OracleBlob) | |
| 918 { | |
| 919 using (var oraBlob = (OracleBlob)value) | |
| 920 return oraBlob.IsNull? DefaultGuidNullValue: new Guid(oraBlob.Value); | |
| 921 } | |
| 922 | |
| 923 return base.ConvertToGuid(value); | |
| 924 } | |
| 925 | |
| 926 public override String ConvertToString(object value) | |
| 927 { | |
| 928 if (value is OracleString) | |
| 929 { | |
| 930 var oraString = (OracleString)value; | |
| 931 return oraString.IsNull? DefaultStringNullValue: oraString.Value; | |
| 932 } | |
| 933 #if !MANAGED | |
| 934 if (value is OracleXmlType) | |
| 935 { | |
| 936 var oraXmlType = (OracleXmlType)value; | |
| 937 return oraXmlType.IsNull ? DefaultStringNullValue : oraXmlType.Value; | |
| 938 } | |
| 939 #endif | |
| 940 if (value is OracleClob) | |
| 941 { | |
| 942 using (var oraClob = (OracleClob)value) | |
| 943 return oraClob.IsNull? DefaultStringNullValue: oraClob.Value; | |
| 944 } | |
| 945 | |
| 946 return base.ConvertToString(value); | |
| 947 } | |
| 948 | |
| 949 #if !MANAGED | |
| 950 public override Stream ConvertToStream(object value) | |
| 951 { | |
| 952 if (value is OracleXmlType) | |
| 953 { | |
| 954 var oraXml = (OracleXmlType)value; | |
| 955 return oraXml.IsNull? DefaultStreamNullValue: oraXml.GetStream(); | |
| 956 } | |
| 957 | |
| 958 return base.ConvertToStream(value); | |
| 959 } | |
| 960 | |
| 961 public override XmlReader ConvertToXmlReader(object value) | |
| 962 { | |
| 963 if (value is OracleXmlType) | |
| 964 { | |
| 965 var oraXml = (OracleXmlType)value; | |
| 966 return oraXml.IsNull? DefaultXmlReaderNullValue: oraXml.GetXmlReader(); | |
| 967 } | |
| 968 | |
| 969 return base.ConvertToXmlReader(value); | |
| 970 } | |
| 971 | |
| 972 public override XmlDocument ConvertToXmlDocument(object value) | |
| 973 { | |
| 974 if (value is OracleXmlType) | |
| 975 { | |
| 976 var oraXml = (OracleXmlType)value; | |
| 977 return oraXml.IsNull? DefaultXmlDocumentNullValue: oraXml.GetXmlDocument(); | |
| 978 } | |
| 979 | |
| 980 return base.ConvertToXmlDocument(value); | |
| 981 } | |
| 982 #endif | |
| 983 | |
| 984 public override Byte[] ConvertToByteArray(object value) | |
| 985 { | |
| 986 if (value is OracleBlob) | |
| 987 { | |
| 988 using (var oraBlob = (OracleBlob)value) | |
| 989 return oraBlob.IsNull? null: oraBlob.Value; | |
| 990 } | |
| 991 | |
| 992 if (value is OracleBinary) | |
| 993 { | |
| 994 var oraBinary = (OracleBinary)value; | |
| 995 return oraBinary.IsNull? null: oraBinary.Value; | |
| 996 } | |
| 997 | |
| 998 if (value is OracleBFile) | |
| 999 { | |
| 1000 var oraBFile = (OracleBFile)value; | |
| 1001 return oraBFile.IsNull? null: oraBFile.Value; | |
| 1002 } | |
| 1003 | |
| 1004 return base.ConvertToByteArray(value); | |
| 1005 } | |
| 1006 | |
| 1007 public override Char[] ConvertToCharArray(object value) | |
| 1008 { | |
| 1009 if (value is OracleString) | |
| 1010 { | |
| 1011 var oraString = (OracleString)value; | |
| 1012 return oraString.IsNull? null: oraString.Value.ToCharArray(); | |
| 1013 } | |
| 1014 | |
| 1015 if (value is OracleClob) | |
| 1016 { | |
| 1017 using (var oraClob = (OracleClob)value) | |
| 1018 return oraClob.IsNull? null: oraClob.Value.ToCharArray(); | |
| 1019 } | |
| 1020 | |
| 1021 return base.ConvertToCharArray(value); | |
| 1022 } | |
| 1023 | |
| 1024 #endregion | |
| 1025 | |
| 1026 #region Nullable Types | |
| 1027 | |
| 1028 [CLSCompliant(false)] | |
| 1029 public override SByte? ConvertToNullableSByte(object value) | |
| 1030 { | |
| 1031 if (value is OracleDecimal) | |
| 1032 { | |
| 1033 var oraDecimal = (OracleDecimal)value; | |
| 1034 return oraDecimal.IsNull? null: (SByte?)oraDecimal.Value; | |
| 1035 } | |
| 1036 | |
| 1037 return base.ConvertToNullableSByte(value); | |
| 1038 } | |
| 1039 | |
| 1040 public override Int16? ConvertToNullableInt16(object value) | |
| 1041 { | |
| 1042 if (value is OracleDecimal) | |
| 1043 { | |
| 1044 var oraDecimal = (OracleDecimal)value; | |
| 1045 return oraDecimal.IsNull? null: (Int16?)oraDecimal.ToInt16(); | |
| 1046 } | |
| 1047 | |
| 1048 return base.ConvertToNullableInt16(value); | |
| 1049 } | |
| 1050 | |
| 1051 public override Int32? ConvertToNullableInt32(object value) | |
| 1052 { | |
| 1053 if (value is OracleDecimal) | |
| 1054 { | |
| 1055 var oraDecimal = (OracleDecimal)value; | |
| 1056 return oraDecimal.IsNull? null: (Int32?)oraDecimal.ToInt32(); | |
| 1057 } | |
| 1058 | |
| 1059 return base.ConvertToNullableInt32(value); | |
| 1060 } | |
| 1061 | |
| 1062 public override Int64? ConvertToNullableInt64(object value) | |
| 1063 { | |
| 1064 if (value is OracleDecimal) | |
| 1065 { | |
| 1066 var oraDecimal = (OracleDecimal)value; | |
| 1067 return oraDecimal.IsNull? null: (Int64?)oraDecimal.ToInt64(); | |
| 1068 } | |
| 1069 | |
| 1070 return base.ConvertToNullableInt64(value); | |
| 1071 } | |
| 1072 | |
| 1073 public override Byte? ConvertToNullableByte(object value) | |
| 1074 { | |
| 1075 if (value is OracleDecimal) | |
| 1076 { | |
| 1077 var oraDecimal = (OracleDecimal)value; | |
| 1078 return oraDecimal.IsNull? null: (Byte?)oraDecimal.ToByte(); | |
| 1079 } | |
| 1080 | |
| 1081 return base.ConvertToNullableByte(value); | |
| 1082 } | |
| 1083 | |
| 1084 [CLSCompliant(false)] | |
| 1085 public override UInt16? ConvertToNullableUInt16(object value) | |
| 1086 { | |
| 1087 if (value is OracleDecimal) | |
| 1088 { | |
| 1089 var oraDecimal = (OracleDecimal)value; | |
| 1090 return oraDecimal.IsNull? null: (UInt16?)oraDecimal.Value; | |
| 1091 } | |
| 1092 | |
| 1093 return base.ConvertToNullableUInt16(value); | |
| 1094 } | |
| 1095 | |
| 1096 [CLSCompliant(false)] | |
| 1097 public override UInt32? ConvertToNullableUInt32(object value) | |
| 1098 { | |
| 1099 if (value is OracleDecimal) | |
| 1100 { | |
| 1101 var oraDecimal = (OracleDecimal)value; | |
| 1102 return oraDecimal.IsNull? null: (UInt32?)oraDecimal.Value; | |
| 1103 } | |
| 1104 | |
| 1105 return base.ConvertToNullableUInt32(value); | |
| 1106 } | |
| 1107 | |
| 1108 [CLSCompliant(false)] | |
| 1109 public override UInt64? ConvertToNullableUInt64(object value) | |
| 1110 { | |
| 1111 if (value is OracleDecimal) | |
| 1112 { | |
| 1113 var oraDecimal = (OracleDecimal)value; | |
| 1114 return oraDecimal.IsNull? null: (UInt64?)oraDecimal.Value; | |
| 1115 } | |
| 1116 | |
| 1117 return base.ConvertToNullableUInt64(value); | |
| 1118 } | |
| 1119 | |
| 1120 public override Single? ConvertToNullableSingle(object value) | |
| 1121 { | |
| 1122 if (value is OracleDecimal) | |
| 1123 { | |
| 1124 var oraDecimal = (OracleDecimal)value; | |
| 1125 return oraDecimal.IsNull? null: (Single?)oraDecimal.ToSingle(); | |
| 1126 } | |
| 1127 | |
| 1128 return base.ConvertToNullableSingle(value); | |
| 1129 } | |
| 1130 | |
| 1131 public override Double? ConvertToNullableDouble(object value) | |
| 1132 { | |
| 1133 if (value is OracleDecimal) | |
| 1134 { | |
| 1135 var oraDecimal = (OracleDecimal)value; | |
| 1136 return oraDecimal.IsNull? null: (Double?)oraDecimal.ToDouble(); | |
| 1137 } | |
| 1138 | |
| 1139 return base.ConvertToNullableDouble(value); | |
| 1140 } | |
| 1141 | |
| 1142 public override Boolean? ConvertToNullableBoolean(object value) | |
| 1143 { | |
| 1144 if (value is OracleDecimal) | |
| 1145 { | |
| 1146 var oraDecimal = (OracleDecimal)value; | |
| 1147 return oraDecimal.IsNull? null: (Boolean?)(oraDecimal.Value != 0); | |
| 1148 } | |
| 1149 | |
| 1150 return base.ConvertToNullableBoolean(value); | |
| 1151 } | |
| 1152 | |
| 1153 public override DateTime? ConvertToNullableDateTime(object value) | |
| 1154 { | |
| 1155 if (value is OracleDate) | |
| 1156 { | |
| 1157 var oraDate = (OracleDate)value; | |
| 1158 return oraDate.IsNull? null: (DateTime?)oraDate.Value; | |
| 1159 } | |
| 1160 | |
| 1161 return base.ConvertToNullableDateTime(value); | |
| 1162 } | |
| 1163 | |
| 1164 public override Decimal? ConvertToNullableDecimal(object value) | |
| 1165 { | |
| 1166 if (value is OracleDecimal) | |
| 1167 { | |
| 1168 var oraDecimal = (OracleDecimal)value; | |
| 1169 return oraDecimal.IsNull? null: (Decimal?)oraDecimal.Value; | |
| 1170 } | |
| 1171 | |
| 1172 return base.ConvertToNullableDecimal(value); | |
| 1173 } | |
| 1174 | |
| 1175 public override Guid? ConvertToNullableGuid(object value) | |
| 1176 { | |
| 1177 if (value is OracleString) | |
| 1178 { | |
| 1179 var oraString = (OracleString)value; | |
| 1180 return oraString.IsNull? null: (Guid?)new Guid(oraString.Value); | |
| 1181 } | |
| 1182 | |
| 1183 if (value is OracleBlob) | |
| 1184 { | |
| 1185 using (var oraBlob = (OracleBlob)value) | |
| 1186 return oraBlob.IsNull? null: (Guid?)new Guid(oraBlob.Value); | |
| 1187 } | |
| 1188 | |
| 1189 return base.ConvertToNullableGuid(value); | |
| 1190 } | |
| 1191 | |
| 1192 #endregion | |
| 1193 | |
| 1194 #endregion | |
| 1195 | |
| 1196 public override object MapValueToEnum(object value, Type type) | |
| 1197 { | |
| 1198 if (value is OracleString) | |
| 1199 { | |
| 1200 var oracleValue = (OracleString)value; | |
| 1201 value = oracleValue.IsNull? null: oracleValue.Value; | |
| 1202 } | |
| 1203 else if (value is OracleDecimal) | |
| 1204 { | |
| 1205 var oracleValue = (OracleDecimal)value; | |
| 1206 if (oracleValue.IsNull) | |
| 1207 value = null; | |
| 1208 else | |
| 1209 value = oracleValue.Value; | |
| 1210 } | |
| 1211 | |
| 1212 return base.MapValueToEnum(value, type); | |
| 1213 } | |
| 1214 | |
| 1215 public override object MapValueToEnum(object value, MemberAccessor ma) | |
| 1216 { | |
| 1217 if (value is OracleString) | |
| 1218 { | |
| 1219 var oracleValue = (OracleString)value; | |
| 1220 value = oracleValue.IsNull ? null : oracleValue.Value; | |
| 1221 } | |
| 1222 else if (value is OracleDecimal) | |
| 1223 { | |
| 1224 var oracleValue = (OracleDecimal)value; | |
| 1225 if (oracleValue.IsNull) | |
| 1226 value = null; | |
| 1227 else | |
| 1228 value = oracleValue.Value; | |
| 1229 } | |
| 1230 | |
| 1231 return base.MapValueToEnum(value, ma); | |
| 1232 } | |
| 1233 | |
| 1234 public override object ConvertChangeType(object value, Type conversionType) | |
| 1235 { | |
| 1236 // Handle OracleDecimal with IsNull == true case | |
| 1237 // | |
| 1238 return base.ConvertChangeType(IsNull(value)? null: value, conversionType); | |
| 1239 } | |
| 1240 | |
| 1241 public override bool IsNull(object value) | |
| 1242 { | |
| 1243 // ODP 10 does not expose this interface to public. | |
| 1244 // | |
| 1245 // return value is INullable && ((INullable)value).IsNull; | |
| 1246 | |
| 1247 return | |
| 1248 value is OracleDecimal? ((OracleDecimal) value).IsNull: | |
| 1249 value is OracleString? ((OracleString) value).IsNull: | |
| 1250 value is OracleDate? ((OracleDate) value).IsNull: | |
| 1251 value is OracleTimeStamp? ((OracleTimeStamp) value).IsNull: | |
| 1252 value is OracleTimeStampTZ? ((OracleTimeStampTZ) value).IsNull: | |
| 1253 value is OracleTimeStampLTZ? ((OracleTimeStampLTZ)value).IsNull: | |
| 1254 #if !MANAGED | |
| 1255 value is OracleXmlType? ((OracleXmlType) value).IsNull: | |
| 1256 #endif | |
| 1257 value is OracleBlob? ((OracleBlob) value).IsNull: | |
| 1258 value is OracleClob? ((OracleClob) value).IsNull: | |
| 1259 value is OracleBFile? ((OracleBFile) value).IsNull: | |
| 1260 value is OracleBinary? ((OracleBinary) value).IsNull: | |
| 1261 value is OracleIntervalDS? ((OracleIntervalDS) value).IsNull: | |
| 1262 value is OracleIntervalYM? ((OracleIntervalYM) value).IsNull: | |
| 1263 base.IsNull(value); | |
| 1264 } | |
| 1265 } | |
| 1266 | |
| 1267 // TODO: implement via IDataReaderEx / DataReaderEx | |
| 1268 // | |
| 1269 public class OracleDataReaderMapper : DataReaderMapper | |
| 1270 { | |
| 1271 public OracleDataReaderMapper(MappingSchema mappingSchema, IDataReader dataReader) | |
| 1272 : base(mappingSchema, dataReader) | |
| 1273 { | |
| 1274 _dataReader = dataReader is OracleDataReaderEx? | |
| 1275 ((OracleDataReaderEx)dataReader).DataReader: | |
| 1276 (OracleDataReader)dataReader; | |
| 1277 } | |
| 1278 | |
| 1279 private readonly OracleDataReader _dataReader; | |
| 1280 | |
| 1281 public override Type GetFieldType(int index) | |
| 1282 { | |
| 1283 var fieldType = _dataReader.GetProviderSpecificFieldType(index); | |
| 1284 | |
| 1285 if (fieldType != typeof(OracleBlob) | |
| 1286 #if !MANAGED | |
| 1287 && fieldType != typeof(OracleXmlType) | |
| 1288 #endif | |
| 1289 ) | |
| 1290 fieldType = _dataReader.GetFieldType(index); | |
| 1291 | |
| 1292 return fieldType; | |
| 1293 } | |
| 1294 | |
| 1295 public override object GetValue(object o, int index) | |
| 1296 { | |
| 1297 var fieldType = _dataReader.GetProviderSpecificFieldType(index); | |
| 1298 | |
| 1299 #if !MANAGED | |
| 1300 if (fieldType == typeof(OracleXmlType)) | |
| 1301 { | |
| 1302 var xml = _dataReader.GetOracleXmlType(index); | |
| 1303 return MappingSchema.ConvertToXmlDocument(xml); | |
| 1304 } | |
| 1305 #endif | |
| 1306 if (fieldType == typeof(OracleBlob)) | |
| 1307 { | |
| 1308 var blob = _dataReader.GetOracleBlob(index); | |
| 1309 return MappingSchema.ConvertToStream(blob); | |
| 1310 } | |
| 1311 | |
| 1312 return _dataReader.IsDBNull(index)? null: | |
| 1313 _dataReader.GetValue(index); | |
| 1314 } | |
| 1315 | |
| 1316 public override Boolean GetBoolean(object o, int index) { return MappingSchema.ConvertToBoolean(GetValue(o, index)); } | |
| 1317 public override Char GetChar (object o, int index) { return MappingSchema.ConvertToChar (GetValue(o, index)); } | |
| 1318 public override Guid GetGuid (object o, int index) { return MappingSchema.ConvertToGuid (GetValue(o, index)); } | |
| 1319 | |
| 1320 [CLSCompliant(false)] | |
| 1321 public override SByte GetSByte (object o, int index) { return (SByte)_dataReader.GetDecimal(index); } | |
| 1322 [CLSCompliant(false)] | |
| 1323 public override UInt16 GetUInt16 (object o, int index) { return (UInt16)_dataReader.GetDecimal(index); } | |
| 1324 [CLSCompliant(false)] | |
| 1325 public override UInt32 GetUInt32 (object o, int index) { return (UInt32)_dataReader.GetDecimal(index); } | |
| 1326 [CLSCompliant(false)] | |
| 1327 public override UInt64 GetUInt64 (object o, int index) { return (UInt64)_dataReader.GetDecimal(index); } | |
| 1328 | |
| 1329 public override Decimal GetDecimal(object o, int index) { return OracleDecimal.SetPrecision(_dataReader.GetOracleDecimal(index), 28).Value; } | |
| 1330 | |
| 1331 public override Boolean? GetNullableBoolean(object o, int index) { return MappingSchema.ConvertToNullableBoolean(GetValue(o, index)); } | |
| 1332 public override Char? GetNullableChar (object o, int index) { return MappingSchema.ConvertToNullableChar (GetValue(o, index)); } | |
| 1333 public override Guid? GetNullableGuid (object o, int index) { return MappingSchema.ConvertToNullableGuid (GetValue(o, index)); } | |
| 1334 | |
| 1335 [CLSCompliant(false)] | |
| 1336 public override SByte? GetNullableSByte (object o, int index) { return _dataReader.IsDBNull(index)? null: (SByte?)_dataReader.GetDecimal(index); } | |
| 1337 [CLSCompliant(false)] | |
| 1338 public override UInt16? GetNullableUInt16 (object o, int index) { return _dataReader.IsDBNull(index)? null: (UInt16?)_dataReader.GetDecimal(index); } | |
| 1339 [CLSCompliant(false)] | |
| 1340 public override UInt32? GetNullableUInt32 (object o, int index) { return _dataReader.IsDBNull(index)? null: (UInt32?)_dataReader.GetDecimal(index); } | |
| 1341 [CLSCompliant(false)] | |
| 1342 public override UInt64? GetNullableUInt64 (object o, int index) { return _dataReader.IsDBNull(index)? null: (UInt64?)_dataReader.GetDecimal(index); } | |
| 1343 | |
| 1344 public override Decimal? GetNullableDecimal(object o, int index) { return _dataReader.IsDBNull(index)? (decimal?)null: OracleDecimal.SetPrecision(_dataReader.GetOracleDecimal(index), 28).Value; } | |
| 1345 } | |
| 1346 | |
| 1347 public class OracleScalarDataReaderMapper : ScalarDataReaderMapper | |
| 1348 { | |
| 1349 private readonly OracleDataReader _dataReader; | |
| 1350 | |
| 1351 public OracleScalarDataReaderMapper( | |
| 1352 MappingSchema mappingSchema, | |
| 1353 IDataReader dataReader, | |
| 1354 NameOrIndexParameter nameOrIndex) | |
| 1355 : base(mappingSchema, dataReader, nameOrIndex) | |
| 1356 { | |
| 1357 _dataReader = dataReader is OracleDataReaderEx? | |
| 1358 ((OracleDataReaderEx)dataReader).DataReader: | |
| 1359 (OracleDataReader)dataReader; | |
| 1360 | |
| 1361 _fieldType = _dataReader.GetProviderSpecificFieldType(Index); | |
| 1362 | |
| 1363 if (_fieldType != typeof(OracleBlob) | |
| 1364 #if !MANAGED | |
| 1365 && _fieldType != typeof(OracleXmlType) | |
| 1366 #endif | |
| 1367 ) | |
| 1368 _fieldType = _dataReader.GetFieldType(Index); | |
| 1369 } | |
| 1370 | |
| 1371 private readonly Type _fieldType; | |
| 1372 | |
| 1373 public override Type GetFieldType(int index) | |
| 1374 { | |
| 1375 return _fieldType; | |
| 1376 } | |
| 1377 | |
| 1378 public override object GetValue(object o, int index) | |
| 1379 { | |
| 1380 #if !MANAGED | |
| 1381 if (_fieldType == typeof(OracleXmlType)) | |
| 1382 { | |
| 1383 var xml = _dataReader.GetOracleXmlType(Index); | |
| 1384 return MappingSchema.ConvertToXmlDocument(xml); | |
| 1385 } | |
| 1386 #endif | |
| 1387 if (_fieldType == typeof(OracleBlob)) | |
| 1388 { | |
| 1389 var blob = _dataReader.GetOracleBlob(Index); | |
| 1390 return MappingSchema.ConvertToStream(blob); | |
| 1391 } | |
| 1392 | |
| 1393 return _dataReader.IsDBNull(index)? null: | |
| 1394 _dataReader.GetValue(Index); | |
| 1395 } | |
| 1396 | |
| 1397 public override Boolean GetBoolean(object o, int index) { return MappingSchema.ConvertToBoolean(GetValue(o, Index)); } | |
| 1398 public override Char GetChar (object o, int index) { return MappingSchema.ConvertToChar (GetValue(o, Index)); } | |
| 1399 public override Guid GetGuid (object o, int index) { return MappingSchema.ConvertToGuid (GetValue(o, Index)); } | |
| 1400 | |
| 1401 [CLSCompliant(false)] | |
| 1402 public override SByte GetSByte (object o, int index) { return (SByte)_dataReader.GetDecimal(Index); } | |
| 1403 [CLSCompliant(false)] | |
| 1404 public override UInt16 GetUInt16 (object o, int index) { return (UInt16)_dataReader.GetDecimal(Index); } | |
| 1405 [CLSCompliant(false)] | |
| 1406 public override UInt32 GetUInt32 (object o, int index) { return (UInt32)_dataReader.GetDecimal(Index); } | |
| 1407 [CLSCompliant(false)] | |
| 1408 public override UInt64 GetUInt64 (object o, int index) { return (UInt64)_dataReader.GetDecimal(Index); } | |
| 1409 | |
| 1410 public override Decimal GetDecimal(object o, int index) { return OracleDecimal.SetPrecision(_dataReader.GetOracleDecimal(Index), 28).Value; } | |
| 1411 | |
| 1412 public override Boolean? GetNullableBoolean(object o, int index) { return MappingSchema.ConvertToNullableBoolean(GetValue(o, Index)); } | |
| 1413 public override Char? GetNullableChar (object o, int index) { return MappingSchema.ConvertToNullableChar (GetValue(o, Index)); } | |
| 1414 public override Guid? GetNullableGuid (object o, int index) { return MappingSchema.ConvertToNullableGuid (GetValue(o, Index)); } | |
| 1415 | |
| 1416 [CLSCompliant(false)] | |
| 1417 public override SByte? GetNullableSByte (object o, int index) { return _dataReader.IsDBNull(index)? null: (SByte?)_dataReader.GetDecimal(Index); } | |
| 1418 [CLSCompliant(false)] | |
| 1419 public override UInt16? GetNullableUInt16 (object o, int index) { return _dataReader.IsDBNull(index)? null: (UInt16?)_dataReader.GetDecimal(Index); } | |
| 1420 [CLSCompliant(false)] | |
| 1421 public override UInt32? GetNullableUInt32 (object o, int index) { return _dataReader.IsDBNull(index)? null: (UInt32?)_dataReader.GetDecimal(Index); } | |
| 1422 [CLSCompliant(false)] | |
| 1423 public override UInt64? GetNullableUInt64 (object o, int index) { return _dataReader.IsDBNull(index)? null: (UInt64?)_dataReader.GetDecimal(Index); } | |
| 1424 | |
| 1425 public override Decimal? GetNullableDecimal(object o, int index) { return _dataReader.IsDBNull(index)? (decimal?)null: OracleDecimal.SetPrecision(_dataReader.GetOracleDecimal(Index), 28).Value; } | |
| 1426 } | |
| 1427 | |
| 1428 [Mixin(typeof(IDbDataParameter), "_oracleParameter")] | |
| 1429 [Mixin(typeof(IDataParameter), "_oracleParameter")] | |
| 1430 [Mixin(typeof(IDisposable), "_oracleParameter")] | |
| 1431 [Mixin(typeof(ICloneable), "_oracleParameter")] | |
| 1432 [CLSCompliant(false)] | |
| 1433 public abstract class OracleParameterWrap | |
| 1434 { | |
| 1435 protected OracleParameter _oracleParameter; | |
| 1436 public OracleParameter OracleParameter | |
| 1437 { | |
| 1438 get { return _oracleParameter; } | |
| 1439 } | |
| 1440 | |
| 1441 public static IDbDataParameter CreateInstance(OracleParameter oraParameter) | |
| 1442 { | |
| 1443 var wrap = TypeAccessor<OracleParameterWrap>.CreateInstanceEx(); | |
| 1444 | |
| 1445 wrap._oracleParameter = oraParameter; | |
| 1446 | |
| 1447 return (IDbDataParameter)wrap; | |
| 1448 } | |
| 1449 | |
| 1450 public override string ToString() | |
| 1451 { | |
| 1452 return _oracleParameter.ToString(); | |
| 1453 } | |
| 1454 | |
| 1455 ///<summary> | |
| 1456 ///Gets or sets the value of the parameter. | |
| 1457 ///</summary> | |
| 1458 ///<returns> | |
| 1459 ///An <see cref="T:System.Object"/> that is the value of the parameter. | |
| 1460 ///The default value is null. | |
| 1461 ///</returns> | |
| 1462 protected object Value | |
| 1463 { | |
| 1464 #if CONVERTORACLETYPES | |
| 1465 [MixinOverride] | |
| 1466 get | |
| 1467 { | |
| 1468 object value = _oracleParameter.Value; | |
| 1469 if (value is OracleBinary) | |
| 1470 { | |
| 1471 OracleBinary oracleValue = (OracleBinary)value; | |
| 1472 return oracleValue.IsNull? null: oracleValue.Value; | |
| 1473 } | |
| 1474 if (value is OracleDate) | |
| 1475 { | |
| 1476 OracleDate oracleValue = (OracleDate)value; | |
| 1477 if (oracleValue.IsNull) | |
| 1478 return null; | |
| 1479 return oracleValue.Value; | |
| 1480 } | |
| 1481 if (value is OracleDecimal) | |
| 1482 { | |
| 1483 OracleDecimal oracleValue = (OracleDecimal)value; | |
| 1484 if (oracleValue.IsNull) | |
| 1485 return null; | |
| 1486 return oracleValue.Value; | |
| 1487 } | |
| 1488 if (value is OracleIntervalDS) | |
| 1489 { | |
| 1490 OracleIntervalDS oracleValue = (OracleIntervalDS)value; | |
| 1491 if (oracleValue.IsNull) | |
| 1492 return null; | |
| 1493 return oracleValue.Value; | |
| 1494 } | |
| 1495 if (value is OracleIntervalYM) | |
| 1496 { | |
| 1497 OracleIntervalYM oracleValue = (OracleIntervalYM)value; | |
| 1498 if (oracleValue.IsNull) | |
| 1499 return null; | |
| 1500 return oracleValue.Value; | |
| 1501 } | |
| 1502 if (value is OracleString) | |
| 1503 { | |
| 1504 OracleString oracleValue = (OracleString)value; | |
| 1505 return oracleValue.IsNull? null: oracleValue.Value; | |
| 1506 } | |
| 1507 if (value is OracleTimeStamp) | |
| 1508 { | |
| 1509 OracleTimeStamp oracleValue = (OracleTimeStamp)value; | |
| 1510 if (oracleValue.IsNull) | |
| 1511 return null; | |
| 1512 return oracleValue.Value; | |
| 1513 } | |
| 1514 if (value is OracleTimeStampLTZ) | |
| 1515 { | |
| 1516 OracleTimeStampLTZ oracleValue = (OracleTimeStampLTZ)value; | |
| 1517 if (oracleValue.IsNull) | |
| 1518 return null; | |
| 1519 return oracleValue.Value; | |
| 1520 } | |
| 1521 if (value is OracleTimeStampTZ) | |
| 1522 { | |
| 1523 OracleTimeStampTZ oracleValue = (OracleTimeStampTZ)value; | |
| 1524 if (oracleValue.IsNull) | |
| 1525 return null; | |
| 1526 return oracleValue.Value; | |
| 1527 } | |
| 1528 if (value is OracleXmlType) | |
| 1529 { | |
| 1530 OracleXmlType oracleValue = (OracleXmlType)value; | |
| 1531 return oracleValue.IsNull? null: oracleValue.Value; | |
| 1532 } | |
| 1533 | |
| 1534 return value; | |
| 1535 } | |
| 1536 #endif | |
| 1537 [MixinOverride] | |
| 1538 set | |
| 1539 { | |
| 1540 if (null != value) | |
| 1541 { | |
| 1542 if (value is Guid) | |
| 1543 { | |
| 1544 // Fix Oracle.Net bug #6: guid type is not handled | |
| 1545 // | |
| 1546 value = ((Guid)value).ToByteArray(); | |
| 1547 } | |
| 1548 else if (value is Array && !(value is byte[] || value is char[])) | |
| 1549 { | |
| 1550 _oracleParameter.CollectionType = OracleCollectionType.PLSQLAssociativeArray; | |
| 1551 } | |
| 1552 else if (value is IConvertible) | |
| 1553 { | |
| 1554 var convertible = (IConvertible)value; | |
| 1555 var typeCode = convertible.GetTypeCode(); | |
| 1556 | |
| 1557 switch (typeCode) | |
| 1558 { | |
| 1559 case TypeCode.Boolean: | |
| 1560 // Fix Oracle.Net bug #7: bool type is handled wrong | |
| 1561 // | |
| 1562 value = convertible.ToByte(null); | |
| 1563 break; | |
| 1564 | |
| 1565 case TypeCode.SByte: | |
| 1566 case TypeCode.UInt16: | |
| 1567 case TypeCode.UInt32: | |
| 1568 case TypeCode.UInt64: | |
| 1569 // Fix Oracle.Net bug #8: some integer types are handled wrong | |
| 1570 // | |
| 1571 value = convertible.ToDecimal(null); | |
| 1572 break; | |
| 1573 | |
| 1574 // Fix Oracle.Net bug #10: zero-length string can not be converted to | |
| 1575 // ORAXML type, but null value can be. | |
| 1576 // | |
| 1577 case TypeCode.String: | |
| 1578 if (((string)value).Length == 0) | |
| 1579 value = null; | |
| 1580 break; | |
| 1581 | |
| 1582 default: | |
| 1583 // Fix Oracle.Net bug #5: Enum type is not handled | |
| 1584 // | |
| 1585 if (value is Enum) | |
| 1586 { | |
| 1587 // Convert a Enum value to it's underlying type. | |
| 1588 // | |
| 1589 value = System.Convert.ChangeType(value, typeCode); | |
| 1590 } | |
| 1591 break; | |
| 1592 } | |
| 1593 } | |
| 1594 } | |
| 1595 | |
| 1596 _oracleParameter.Value = value; | |
| 1597 } | |
| 1598 } | |
| 1599 } | |
| 1600 | |
| 1601 #endregion | |
| 1602 | |
| 1603 #region InsertBatch | |
| 1604 | |
| 1605 public override int InsertBatch<T>( | |
| 1606 DbManager db, | |
| 1607 string insertText, | |
| 1608 IEnumerable<T> collection, | |
| 1609 MemberMapper[] members, | |
| 1610 int maxBatchSize, | |
| 1611 DbManager.ParameterProvider<T> getParameters) | |
| 1612 { | |
| 1613 var sb = new StringBuilder(); | |
| 1614 var sp = new OracleSqlProvider(); | |
| 1615 var pn = 0; | |
| 1616 var n = 0; | |
| 1617 var cnt = 0; | |
| 1618 var str = "\t" + insertText | |
| 1619 .Substring(0, insertText.IndexOf(") VALUES (")) | |
| 1620 .Substring(7) | |
| 1621 .Replace("\r", "") | |
| 1622 .Replace("\n", "") | |
| 1623 .Replace("\t", " ") | |
| 1624 .Replace("( ", "(") | |
| 1625 //.Replace(" ", " ") | |
| 1626 + ") VALUES ("; | |
| 1627 | |
| 1628 var parameters = new List<IDbDataParameter>(); | |
| 1629 | |
| 1630 foreach (var item in collection) | |
| 1631 { | |
| 1632 if (sb.Length == 0) | |
| 1633 sb.AppendLine("INSERT ALL"); | |
| 1634 | |
| 1635 sb.Append(str); | |
| 1636 | |
| 1637 foreach (var member in members) | |
| 1638 { | |
| 1639 var value = member.GetValue(item); | |
| 1640 | |
| 1641 if (value != null && value.GetType().IsEnum) | |
| 1642 value = MappingSchema.MapEnumToValue(value, true); | |
| 1643 | |
| 1644 if (value is Nullable<DateTime>) | |
| 1645 value = ((DateTime?)value).Value; | |
| 1646 | |
| 1647 if (value is DateTime) | |
| 1648 { | |
| 1649 var dt = (DateTime)value; | |
| 1650 sb.Append(string.Format("to_timestamp('{0:dd.MM.yyyy HH:mm:ss.ffffff}', 'DD.MM.YYYY HH24:MI:SS.FF6')", dt)); | |
| 1651 } | |
| 1652 else if (value is string && ((string)value).Length >= 2000) | |
| 1653 { | |
| 1654 var par = db.Parameter("p" + ++pn, value); | |
| 1655 parameters.Add(par); | |
| 1656 sb.Append(":" + par.ParameterName); | |
| 1657 } | |
| 1658 else | |
| 1659 sp.BuildValue(sb, value); | |
| 1660 | |
| 1661 sb.Append(", "); | |
| 1662 } | |
| 1663 | |
| 1664 sb.Length -= 2; | |
| 1665 sb.AppendLine(")"); | |
| 1666 | |
| 1667 n++; | |
| 1668 | |
| 1669 if (n >= maxBatchSize) | |
| 1670 { | |
| 1671 sb.AppendLine("SELECT * FROM dual"); | |
| 1672 | |
| 1673 var sql = sb.ToString(); | |
| 1674 | |
| 1675 if (DbManager.TraceSwitch.TraceInfo) | |
| 1676 DbManager.WriteTraceLine("\n" + sql.Replace("\r", ""), DbManager.TraceSwitch.DisplayName); | |
| 1677 | |
| 1678 cnt += db | |
| 1679 .SetCommand(sql, parameters.Count > 0 ? parameters.ToArray() : null) | |
| 1680 .ExecuteNonQuery(); | |
| 1681 | |
| 1682 parameters.Clear(); | |
| 1683 pn = 0; | |
| 1684 n = 0; | |
| 1685 sb.Length = 0; | |
| 1686 } | |
| 1687 } | |
| 1688 | |
| 1689 if (n > 0) | |
| 1690 { | |
| 1691 sb.AppendLine("SELECT * FROM dual"); | |
| 1692 | |
| 1693 var sql = sb.ToString(); | |
| 1694 | |
| 1695 if (DbManager.TraceSwitch.TraceInfo) | |
| 1696 DbManager.WriteTraceLine("\n" + sql.Replace("\r", ""), DbManager.TraceSwitch.DisplayName); | |
| 1697 | |
| 1698 cnt += db | |
| 1699 .SetCommand(sql, parameters.Count > 0 ? parameters.ToArray() : null) | |
| 1700 .ExecuteNonQuery(); | |
| 1701 } | |
| 1702 | |
| 1703 return cnt; | |
| 1704 } | |
| 1705 | |
| 1706 #endregion | |
| 1707 } | |
| 1708 } |
