* SqlException.cs: Do not hide Message on 2.0 profile. Fixes bug
[mono.git] / mcs / class / System.Data / System.Data.SqlClient / SqlParameter.cs
1 //
2 // System.Data.SqlClient.SqlParameter.cs
3 //
4 // Author:
5 //   Rodrigo Moya (rodrigo@ximian.com)
6 //   Daniel Morgan (danmorg@sc.rr.com)
7 //   Tim Coleman (tim@timcoleman.com)
8 //   Diego Caravana (diego@toth.it)
9 //   Umadevi S (sumadevi@novell.com)
10 //   Amit Biswas (amit@amitbiswas.com)
11 //
12 // (C) Ximian, Inc. 2002
13 // Copyright (C) Tim Coleman, 2002
14 //
15
16 //
17 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
18 //
19 // Permission is hereby granted, free of charge, to any person obtaining
20 // a copy of this software and associated documentation files (the
21 // "Software"), to deal in the Software without restriction, including
22 // without limitation the rights to use, copy, modify, merge, publish,
23 // distribute, sublicense, and/or sell copies of the Software, and to
24 // permit persons to whom the Software is furnished to do so, subject to
25 // the following conditions:
26 // 
27 // The above copyright notice and this permission notice shall be
28 // included in all copies or substantial portions of the Software.
29 // 
30 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
31 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
32 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
33 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
34 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
35 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
36 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
37 //
38
39 using Mono.Data.Tds;
40 using Mono.Data.Tds.Protocol;
41 using System;
42 using System.ComponentModel;
43 using System.Data;
44 using System.Data.Common;
45 using System.Data.SqlTypes;
46 using System.Runtime.InteropServices;
47 using System.Text;
48
49 namespace System.Data.SqlClient {
50 #if NET_2_0
51         [TypeConverterAttribute ("System.Data.SqlClient.SqlParameter+SqlParameterConverter, " + Consts.AssemblySystem_Data)]
52         public sealed class SqlParameter : DbParameter, IDbDataParameter, IDataParameter, ICloneable
53 #else
54         [TypeConverterAttribute (typeof (SqlParameterConverter))]
55         public sealed class SqlParameter : MarshalByRefObject, IDbDataParameter, IDataParameter, ICloneable
56 #endif // NET_2_0
57         {
58                 #region Fields
59
60                 TdsMetaParameter metaParameter;
61
62                 SqlParameterCollection container = null;
63                 DbType dbType;
64                 ParameterDirection direction = ParameterDirection.Input;
65                 bool isNullable;
66                 bool isTypeSet = false;
67                 int offset;
68                 SqlDbType sqlDbType;
69                 string sourceColumn;
70                 DataRowVersion sourceVersion;
71                 SqlCompareOptions compareInfo;
72                 int localeId;
73                 Object sqlValue;
74                 string udtTypeName;
75 #if NET_2_0
76                 bool sourceColumnNullMapping;
77                 string xmlSchemaCollectionDatabase = String.Empty;
78                 string xmlSchemaCollectionOwningSchema = String.Empty;
79                 string xmlSchemaCollectionName = String.Empty;
80 #endif
81
82                 #endregion // Fields
83
84                 #region Constructors
85
86                 public SqlParameter () 
87                         : this (String.Empty, SqlDbType.NVarChar, 0, ParameterDirection.Input, false, 0, 0, String.Empty, DataRowVersion.Current, null)
88                 {
89                         isTypeSet = false;
90                 }
91
92                 public SqlParameter (string parameterName, object value) 
93                 {
94                         metaParameter = new TdsMetaParameter (parameterName, value);
95                         InferSqlType (value);
96                         metaParameter.Value =  SqlTypeToFrameworkType (value);
97                         sourceVersion = DataRowVersion.Current;
98                 }
99                 
100                 public SqlParameter (string parameterName, SqlDbType dbType) 
101                         : this (parameterName, dbType, 0, ParameterDirection.Input, false, 0, 0, String.Empty, DataRowVersion.Current, null)
102                 {
103                 }
104
105                 public SqlParameter (string parameterName, SqlDbType dbType, int size) 
106                         : this (parameterName, dbType, size, ParameterDirection.Input, false, 0, 0, String.Empty, DataRowVersion.Current, null)
107                 {
108                 }
109                 
110                 public SqlParameter (string parameterName, SqlDbType dbType, int size, string sourceColumn) 
111                         : this (parameterName, dbType, size, ParameterDirection.Input, false, 0, 0, sourceColumn, DataRowVersion.Current, null)
112                 {
113                 }
114                 
115                 [EditorBrowsable (EditorBrowsableState.Advanced)]        
116                 public SqlParameter (string parameterName, SqlDbType dbType, int size, ParameterDirection direction, bool isNullable, byte precision, byte scale, string sourceColumn, DataRowVersion sourceVersion, object value) 
117                 {
118                         metaParameter = new TdsMetaParameter (parameterName, size, 
119                                                               isNullable, precision, 
120                                                               scale, 
121                                                               value);
122                         if (dbType != SqlDbType.Variant) 
123                                 SqlDbType = dbType;
124                         metaParameter.Value = SqlTypeToFrameworkType (value);
125                         Direction = direction;
126                         SourceColumn = sourceColumn;
127                         SourceVersion = sourceVersion;
128                 }
129
130 #if NET_2_0
131                 public SqlParameter (string parameterName, SqlDbType dbType, int size, ParameterDirection direction, byte precision, byte scale, string sourceColumn, DataRowVersion sourceVersion, bool sourceColumnNullMapping, Object value, string xmlSchemaCollectionDatabase, string xmlSchemaCollectionOwningSchema, string xmlSchemaCollectionName)
132                         : this (parameterName, dbType, size, direction, false, precision, scale, sourceColumn, sourceVersion, value)
133                 {
134                         XmlSchemaCollectionDatabase = xmlSchemaCollectionDatabase;
135                         XmlSchemaCollectionOwningSchema = xmlSchemaCollectionOwningSchema;
136                         XmlSchemaCollectionName = xmlSchemaCollectionName;
137                         SourceColumnNullMapping = sourceColumnNullMapping;
138                 }
139 #endif
140
141                 // This constructor is used internally to construct a
142                 // SqlParameter.  The value array comes from sp_procedure_params_rowset.
143                 // This is in SqlCommand.DeriveParameters.
144                 internal SqlParameter (object[] dbValues) 
145                         : this (dbValues [3].ToString (), String.Empty)
146                 {
147                         Precision = 0;
148                         Scale = 0;
149                         Direction = ParameterDirection.Input;
150
151                         ParameterName = (string) dbValues[3];
152
153                         switch ((short) dbValues[5]) {
154                         case 1:
155                                 Direction = ParameterDirection.Input;
156                                 break;
157                         case 2:
158                                 Direction = ParameterDirection.Output;
159                                 break;
160                         case 3:
161                                 Direction = ParameterDirection.InputOutput;
162                                 break;
163                         case 4:
164                                 Direction = ParameterDirection.ReturnValue;
165                                 break;
166                         default:
167                                 Direction = ParameterDirection.Input;
168                                 break;
169                         }
170                         IsNullable = (dbValues [8] != null && 
171                                 dbValues [8] != DBNull.Value) ? (bool) dbValues [8] : false;
172
173                         if (dbValues [12] != null && dbValues [12] != DBNull.Value)
174                                 Precision = (byte) ((short) dbValues [12]);
175
176                         if (dbValues [13] != null && dbValues [13] != DBNull.Value)
177                                 Scale = (byte) ( (short) dbValues [13]);
178
179                         SetDbTypeName ((string) dbValues [16]);
180                 }
181
182                 #endregion // Constructors
183
184                 #region Properties
185
186                 // Used to ensure that only one collection can contain this
187                 // parameter
188                 internal SqlParameterCollection Container {
189                         get { return container; }
190                         set { container = value; }
191                 }
192
193                 internal void CheckIfInitialized ()
194                 {
195                         if (!isTypeSet)
196                                 throw new Exception ("all parameters to have an explicity set type");
197
198                         if (MetaParameter.IsVariableSizeType) {
199                                 if (SqlDbType == SqlDbType.Decimal && Precision == 0)
200                                         throw new Exception ("Parameter of type 'Decimal' have an explicitly set Precision and Scale");
201                                 else if (Size == 0)
202                                         throw new Exception ("all variable length parameters to have an explicitly set non-zero Size");
203                         }
204                 }
205         
206 #if ONLY_1_0 || ONLY_1_1
207                 [Browsable (false)]
208                 [DataSysDescription ("The parameter generic type.")]
209                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
210                 [RefreshProperties (RefreshProperties.All)]
211                 [DataCategory ("Data")]
212 #endif
213                 public 
214 #if NET_2_0
215                 override
216 #endif // NET_2_0
217                 DbType DbType {
218                         get { return dbType; }
219                         set { 
220                                 SetDbType (value); 
221                                 isTypeSet = true;
222                         }
223                 }
224
225 #if ONLY_1_0 || ONLY_1_1
226                 [DataCategory ("Data")]
227                 [DataSysDescription ("Input, output, or bidirectional parameter.")]
228                 [DefaultValue (ParameterDirection.Input)]
229 #endif
230 #if NET_2_0
231                 [RefreshProperties (RefreshProperties.All)]
232 #endif
233                 public 
234 #if NET_2_0
235                 override
236 #endif // NET_2_0
237          ParameterDirection Direction {
238                         get { return direction; }
239                         set { 
240                                 direction = value; 
241                                 switch( direction ) {
242                                         case ParameterDirection.Output:
243                                         MetaParameter.Direction = TdsParameterDirection.Output;
244                                                 break;
245                                         case ParameterDirection.InputOutput:
246                                                 MetaParameter.Direction = TdsParameterDirection.InputOutput;
247                                                 break;
248                                         case ParameterDirection.ReturnValue:
249                                                 MetaParameter.Direction = TdsParameterDirection.ReturnValue;
250                                                 break;
251                                 }
252                         }
253                 }
254
255                 internal TdsMetaParameter MetaParameter {
256                         get { return metaParameter; }
257                 }
258
259 #if ONLY_1_0 || ONLY_1_1
260                 [Browsable (false)]
261                 [DataSysDescription ("a design-time property used for strongly typed code-generation.")]
262                 [DefaultValue (false)]
263                 [DesignOnly (true)]
264                 [EditorBrowsable (EditorBrowsableState.Advanced)]        
265 #endif
266                 public 
267 #if NET_2_0
268                 override
269 #endif // NET_2_0
270                 bool IsNullable {
271                         get { return metaParameter.IsNullable; }
272                         set { metaParameter.IsNullable = value; }
273                 }
274
275                 [Browsable (false)]
276 #if ONLY_1_0 || ONLY_1_1
277                 [DataCategory ("Data")]
278                 [DataSysDescription ("Offset in variable length data types.")]
279                 [DefaultValue (0)]
280 #endif
281 #if NET_2_0
282                 [EditorBrowsable (EditorBrowsableState.Advanced)]
283 #endif
284                 public int Offset {
285                         get { return offset; }
286                         set { offset = value; }
287                 }
288         
289 #if ONLY_1_0 || ONLY_1_1
290                 [DataSysDescription ("Name of the parameter, like '@p1'")]
291                 [DefaultValue ("")]
292 #endif
293                 public 
294 #if NET_2_0
295                 override
296 #endif // NET_2_0
297                 string ParameterName {
298                         get { return metaParameter.ParameterName; }
299                         set { metaParameter.ParameterName = value; }
300                 }
301
302                 [DefaultValue (0)]
303 #if ONLY_1_0 || ONLY_1_1
304                 [DataCategory ("Data")]
305                 [DataSysDescription ("For decimal, numeric, varnumeric DBTypes.")]
306 #endif
307                 public byte Precision {
308                         get { return metaParameter.Precision; }
309                         set { metaParameter.Precision = value; }
310                 }
311
312                 [DefaultValue (0)]
313 #if ONLY_1_0 || ONLY_1_1
314                 [DataCategory ("Data")]
315                 [DataSysDescription ("For decimal, numeric, varnumeric DBTypes.")]
316 #endif
317                 public byte Scale {
318                         get { return metaParameter.Scale; }
319                         set { metaParameter.Scale = value; }
320                 }
321
322 #if ONLY_1_0 || ONLY_1_1
323                 [DataCategory ("Data")]
324                 [DataSysDescription ("Size of variable length data types (string & arrays).")]
325                 [DefaultValue (0)]
326 #endif
327                 public 
328 #if NET_2_0
329                 override
330 #endif // NET_2_0
331                 int Size {
332                         get { return metaParameter.Size; }
333                         set { metaParameter.Size = value; }
334                 }
335
336 #if ONLY_1_0 || ONLY_1_1
337                 [DataCategory ("Data")]
338                 [DataSysDescription ("When used by a DataAdapter.Update, the source column name that is used to find the DataSetColumn name in the ColumnMappings. This is to copy a value between the parameter and a datarow.")]
339                 [DefaultValue ("")]
340 #endif
341                 public 
342 #if NET_2_0
343                 override
344 #endif // NET_2_0
345                 string SourceColumn {
346                         get { return sourceColumn; }
347                         set { sourceColumn = value; }
348                 }
349
350 #if ONLY_1_0 || ONLY_1_1
351                 [DataCategory ("Data")]
352                 [DataSysDescription ("When used by a DataAdapter.Update (UpdateCommand only), the version of the DataRow value that is used to update the data source.")]
353                 [DefaultValue (DataRowVersion.Current)]
354 #endif
355                 public 
356 #if NET_2_0
357                 override
358 #endif // NET_2_0
359                 DataRowVersion SourceVersion {
360                         get { return sourceVersion; }
361                         set { sourceVersion = value; }
362                 }
363                 
364 #if ONLY_1_0 || ONLY_1_1
365                 [DataCategory ("Data")]
366                 [DataSysDescription ("The parameter native type.")]
367                 [DefaultValue (SqlDbType.NVarChar)]
368 #endif
369                 [RefreshProperties (RefreshProperties.All)]
370 #if NET_2_0
371                 [DbProviderSpecificTypeProperty(true)]
372 #endif
373                 public SqlDbType SqlDbType {
374                         get { return sqlDbType; }
375                         set { 
376                                 SetSqlDbType (value); 
377                                 isTypeSet = true;
378                         }
379                 }
380
381                 [TypeConverterAttribute (typeof (StringConverter))]
382 #if ONLY_1_0 || ONLY_1_1
383                 [DataCategory ("Data")]
384                 [DataSysDescription ("Value of the parameter.")]
385                 [DefaultValue (null)]
386 #else
387                 [RefreshProperties (RefreshProperties.All)]
388 #endif
389                 public 
390 #if NET_2_0
391                 override
392 #endif // NET_2_0
393                 object Value {
394                         get { return metaParameter.Value; }
395                         set {
396                                 if (!isTypeSet)
397                                         InferSqlType (value);
398                                 metaParameter.Value = SqlTypeToFrameworkType (value);
399                         }
400                 }
401
402 #if NET_2_0
403                 [Browsable (false)]
404                 public SqlCompareOptions CompareInfo{
405                         get{ return compareInfo; }
406                         set{ compareInfo = value; }
407                 }
408
409                 [Browsable (false)]
410                 public int LocaleId { 
411                         get { return localeId; }
412                         set { localeId = value; }
413                 }
414
415                 [Browsable (false)]
416                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
417                 public Object SqlValue { 
418                         get { return sqlValue; }
419                         set { sqlValue = value; }
420                 }
421         
422                 public override bool SourceColumnNullMapping {
423                         get { return sourceColumnNullMapping; }
424                         set { sourceColumnNullMapping = value; }
425                 }
426
427                 public string XmlSchemaCollectionDatabase {
428                         get { return xmlSchemaCollectionDatabase; }
429                         set { xmlSchemaCollectionDatabase = (value == null ? String.Empty : value); }
430                 }
431
432                 public string XmlSchemaCollectionName {
433                         get { return xmlSchemaCollectionName; }
434                         set {
435                                 xmlSchemaCollectionName = (value == null ? String.Empty : value);
436                         }
437                 }
438
439                 public string XmlSchemaCollectionOwningSchema {
440                         get { return xmlSchemaCollectionOwningSchema; } 
441                         set {
442                                 xmlSchemaCollectionOwningSchema = (value == null ? String.Empty : value);
443                         }
444                 }
445 #endif
446                 #endregion // Properties
447
448                 #region Methods
449
450                 object ICloneable.Clone ()
451                 {
452                         return new SqlParameter (ParameterName, SqlDbType, Size, Direction, IsNullable, Precision, Scale, SourceColumn, SourceVersion, Value);
453                 }
454
455                 // If the value is set without the DbType/SqlDbType being set, then we
456                 // infer type information.
457                 private void InferSqlType (object value)
458                 {
459                         if (value == null || value == DBNull.Value) {
460                                 SetSqlDbType (SqlDbType.NVarChar);
461                                 return;
462                         }
463
464                         Type type = value.GetType ();
465                         string exception = String.Format ("The parameter data type of {0} is invalid.", type.Name);
466
467                         switch (type.FullName) {
468                         case "System.Int64":
469                         case "System.Data.SqlTypes.SqlInt64":
470                                 SetSqlDbType (SqlDbType.BigInt);
471                                 break;
472                         case "System.Boolean":
473                         case "System.Data.SqlTypes.SqlBoolean":
474                                 SetSqlDbType (SqlDbType.Bit);
475                                 break;
476                         case "System.String":
477                         case "System.Data.SqlTypes.SqlString":
478                                 SetSqlDbType (SqlDbType.NVarChar);
479                                 break;
480                         case "System.DateTime":
481                         case "System.Data.SqlTypes.SqlDateTime":
482                                 SetSqlDbType (SqlDbType.DateTime);
483                                 break;
484                         case "System.Decimal":
485                         case "System.Data.SqlTypes.SqlDecimal":
486                                 SetSqlDbType (SqlDbType.Decimal);
487                                 break;
488                         case "System.Double":
489                         case "System.Data.SqlTypes.SqlDouble":
490                                 SetSqlDbType (SqlDbType.Float);
491                                 break;
492                         case "System.Byte[]":
493                         case "System.Data.SqlTypes.SqlBinary":
494                                 SetSqlDbType (SqlDbType.VarBinary);
495                                 break;
496                         case "System.Byte":
497                         case "System.Data.SqlTypes.SqlByte":
498                                 SetSqlDbType (SqlDbType.TinyInt);
499                                 break;
500                         case "System.Int32":
501                         case "System.Data.SqlTypes.SqlInt32":
502                                 SetSqlDbType (SqlDbType.Int);
503                                 break;
504                         case "System.Single":
505                         case "System.Data.SqlTypes.Single":
506                                 SetSqlDbType (SqlDbType.Real);
507                                 break;
508                         case "System.Int16":
509                         case "System.Data.SqlTypes.SqlInt16":
510                                 SetSqlDbType (SqlDbType.SmallInt);
511                                 break;
512                         case "System.Guid":
513                         case "System.Data.SqlTypes.SqlGuid":
514                                 SetSqlDbType (SqlDbType.UniqueIdentifier);
515                                 break;
516                         case "System.Money":
517                         case "System.SmallMoney":
518                         case "System.Data.SqlTypes.SqlMoney":
519                                 SetSqlDbType (SqlDbType.Money);
520                                 break;
521                         case "System.Object":
522                                 SetSqlDbType (SqlDbType.Variant); 
523                                 break;
524                         default:
525                                 throw new ArgumentException (exception);
526                         }
527                 }
528
529                 // When the DbType is set, we also set the SqlDbType, as well as the SQL Server
530                 // string representation of the type name.  If the DbType is not convertible
531                 // to an SqlDbType, throw an exception.
532                 private void SetDbType (DbType type)
533                 {
534                         string exception = String.Format ("No mapping exists from DbType {0} to a known SqlDbType.", type);
535
536                         switch (type) {
537                         case DbType.AnsiString:
538                                 MetaParameter.TypeName = "varchar";
539                                 sqlDbType = SqlDbType.VarChar;
540                                 MetaParameter.IsVariableSizeType = true;
541                                 break;
542                         case DbType.AnsiStringFixedLength:
543                                 MetaParameter.TypeName = "char";
544                                 sqlDbType = SqlDbType.Char;
545                                 MetaParameter.IsVariableSizeType = true;
546                                 break;
547                         case DbType.Binary:
548                                 MetaParameter.TypeName = "varbinary";
549                                 sqlDbType = SqlDbType.VarBinary;
550                                 MetaParameter.IsVariableSizeType = true;
551                                 break;
552                         case DbType.Boolean:
553                                 MetaParameter.TypeName = "bit";
554                                 sqlDbType = SqlDbType.Bit;
555                                 break;
556                         case DbType.Byte:
557                                 MetaParameter.TypeName = "tinyint";
558                                 sqlDbType = SqlDbType.TinyInt;
559                                 break;
560                         case DbType.Currency:
561                                 sqlDbType = SqlDbType.Money;
562                                 MetaParameter.TypeName = "money";
563                                 break;
564                         case DbType.Date:
565                         case DbType.DateTime:
566                                 MetaParameter.TypeName = "datetime";
567                                 sqlDbType = SqlDbType.DateTime;
568                                 break;
569                         case DbType.Decimal:
570                                 MetaParameter.TypeName = "decimal";
571                                 sqlDbType = SqlDbType.Decimal;
572                                 break;
573                         case DbType.Double:
574                                 MetaParameter.TypeName = "float";
575                                 sqlDbType = SqlDbType.Float;
576                                 break;
577                         case DbType.Guid:
578                                 MetaParameter.TypeName = "uniqueidentifier";
579                                 sqlDbType = SqlDbType.UniqueIdentifier;
580                                 break;
581                         case DbType.Int16:
582                                 MetaParameter.TypeName = "smallint";
583                                 sqlDbType = SqlDbType.SmallInt;
584                                 break;
585                         case DbType.Int32:
586                                 MetaParameter.TypeName = "int";
587                                 sqlDbType = SqlDbType.Int;
588                                 break;
589                         case DbType.Int64:
590                                 MetaParameter.TypeName = "bigint";
591                                 sqlDbType = SqlDbType.BigInt;
592                                 break;
593                         case DbType.Object:
594                                 MetaParameter.TypeName = "sql_variant";
595                                 sqlDbType = SqlDbType.Variant;
596                                 break;
597                         case DbType.Single:
598                                 MetaParameter.TypeName = "real";
599                                 sqlDbType = SqlDbType.Real;
600                                 break;
601                         case DbType.String:
602                                 MetaParameter.TypeName = "nvarchar";
603                                 sqlDbType = SqlDbType.NVarChar;
604                                 MetaParameter.IsVariableSizeType = true;
605                                 break;
606                         case DbType.StringFixedLength:
607                                 MetaParameter.TypeName = "nchar";
608                                 sqlDbType = SqlDbType.NChar;
609                                 MetaParameter.IsVariableSizeType = true;
610                                 break;
611                         case DbType.Time:
612                                 MetaParameter.TypeName = "datetime";
613                                 sqlDbType = SqlDbType.DateTime;
614                                 break;
615                         default:
616                                 throw new ArgumentException (exception);
617                         }
618                         dbType = type;
619                 }
620
621                 // Used by internal constructor which has a SQL Server typename
622                 private void SetDbTypeName (string dbTypeName)
623                 {
624                         switch (dbTypeName.ToLower ()) {        
625                         case "bigint":
626                                 SqlDbType = SqlDbType.BigInt;
627                                 break;
628                         case "binary":
629                                 SqlDbType = SqlDbType.Binary;
630                                 break;
631                         case "bit":
632                                 SqlDbType = SqlDbType.Bit;
633                                 break;
634                         case "char":
635                                 SqlDbType = SqlDbType.Char;
636                                 break;
637                         case "datetime":
638                                 SqlDbType = SqlDbType.DateTime;
639                                 break;
640                         case "decimal":
641                                 SqlDbType = SqlDbType.Decimal;
642                                 break;
643                         case "float":
644                                 SqlDbType = SqlDbType.Float;
645                                 break;
646                         case "image":
647                                 SqlDbType = SqlDbType.Image;
648                                 break;
649                         case "int":
650                                 SqlDbType = SqlDbType.Int;
651                                 break;
652                         case "money":
653                                 SqlDbType = SqlDbType.Money;
654                                 break;
655                         case "nchar":
656                                 SqlDbType = SqlDbType.NChar;
657                                 break;
658                         case "ntext":
659                                 SqlDbType = SqlDbType.NText;
660                                 break;
661                         case "nvarchar":
662                                 SqlDbType = SqlDbType.NVarChar;
663                                 break;
664                         case "real":
665                                 SqlDbType = SqlDbType.Real;
666                                 break;
667                         case "smalldatetime":
668                                 SqlDbType = SqlDbType.SmallDateTime;
669                                 break;
670                         case "smallint":
671                                 SqlDbType = SqlDbType.SmallInt;
672                                 break;
673                         case "smallmoney":
674                                 SqlDbType = SqlDbType.SmallMoney;
675                                 break;
676                         case "text":
677                                 SqlDbType = SqlDbType.Text;
678                                 break;
679                         case "timestamp":
680                                 SqlDbType = SqlDbType.Timestamp;
681                                 break;
682                         case "tinyint":
683                                 SqlDbType = SqlDbType.TinyInt;
684                                 break;
685                         case "uniqueidentifier":
686                                 SqlDbType = SqlDbType.UniqueIdentifier;
687                                 break;
688                         case "varbinary":
689                                 SqlDbType = SqlDbType.VarBinary;
690                                 break;
691                         case "varchar":
692                                 SqlDbType = SqlDbType.VarChar;
693                                 break;
694                         case "sql_variant":
695                                 SqlDbType = SqlDbType.Variant;
696                                 break;
697                         default:
698                                 SqlDbType = SqlDbType.Variant;
699                                 break;
700                         }
701                 }
702
703                 // When the SqlDbType is set, we also set the DbType, as well as the SQL Server
704                 // string representation of the type name.  If the SqlDbType is not convertible
705                 // to a DbType, throw an exception.
706                 internal void SetSqlDbType (SqlDbType type)
707                 {
708                         string exception = String.Format ("No mapping exists from SqlDbType {0} to a known DbType.", type);
709
710                         switch (type) {
711                         case SqlDbType.BigInt:
712                                 MetaParameter.TypeName = "bigint";
713                                 dbType = DbType.Int64;
714                                 break;
715                         case SqlDbType.Binary:
716                                 MetaParameter.TypeName = "binary";
717                                 dbType = DbType.Binary;
718                                 MetaParameter.IsVariableSizeType = true;
719                                 break;
720                         case SqlDbType.Timestamp:
721                                 MetaParameter.TypeName = "timestamp";
722                                 dbType = DbType.Binary;
723                                 break;
724                         case SqlDbType.VarBinary:
725                                 MetaParameter.TypeName = "varbinary";
726                                 dbType = DbType.Binary;
727                                 MetaParameter.IsVariableSizeType = true;
728                                 break;
729                         case SqlDbType.Bit:
730                                 MetaParameter.TypeName = "bit";
731                                 dbType = DbType.Boolean;
732                                 break;
733                         case SqlDbType.Char:
734                                 MetaParameter.TypeName = "char";
735                                 dbType = DbType.AnsiStringFixedLength;
736                                 MetaParameter.IsVariableSizeType = true;
737                                 break;
738                         case SqlDbType.DateTime:
739                                 MetaParameter.TypeName = "datetime";
740                                 dbType = DbType.DateTime;
741                                 break;
742                         case SqlDbType.SmallDateTime:
743                                 MetaParameter.TypeName = "smalldatetime";
744                                 dbType = DbType.DateTime;
745                                 break;
746                         case SqlDbType.Decimal:
747                                 MetaParameter.TypeName = "decimal";
748                                 dbType = DbType.Decimal;
749                                 break;
750                         case SqlDbType.Float:
751                                 MetaParameter.TypeName = "float";
752                                 dbType = DbType.Double;
753                                 break;
754                         case SqlDbType.Image:
755                                 MetaParameter.TypeName = "image";
756                                 dbType = DbType.Binary;
757                                 MetaParameter.IsVariableSizeType = true;
758                                 break;
759                         case SqlDbType.Int:
760                                 MetaParameter.TypeName = "int";
761                                 dbType = DbType.Int32;
762                                 break;
763                         case SqlDbType.Money:
764                                 MetaParameter.TypeName = "money";
765                                 dbType = DbType.Currency;
766                                 break;
767                         case SqlDbType.SmallMoney:
768                                 MetaParameter.TypeName = "smallmoney";
769                                 dbType = DbType.Currency;
770                                 break;
771                         case SqlDbType.NChar:
772                                 MetaParameter.TypeName = "nchar";
773                                 dbType = DbType.StringFixedLength;
774                                 MetaParameter.IsVariableSizeType = true;
775                                 break;
776                         case SqlDbType.NText:
777                                 MetaParameter.TypeName = "ntext";
778                                 dbType = DbType.String;
779                                 MetaParameter.IsVariableSizeType = true;
780                                 break;
781                         case SqlDbType.NVarChar:
782                                 MetaParameter.TypeName = "nvarchar";
783                                 dbType = DbType.String;
784                                 MetaParameter.IsVariableSizeType = true;
785                                 break;
786                         case SqlDbType.Real:
787                                 MetaParameter.TypeName = "real";
788                                 dbType = DbType.Single;
789                                 break;
790                         case SqlDbType.SmallInt:
791                                 MetaParameter.TypeName = "smallint";
792                                 dbType = DbType.Int16;
793                                 break;
794                         case SqlDbType.Text:
795                                 MetaParameter.TypeName = "text";
796                                 dbType = DbType.AnsiString;
797                                 MetaParameter.IsVariableSizeType = true;
798                                 break;
799                         case SqlDbType.VarChar:
800                                 MetaParameter.TypeName = "varchar";
801                                 dbType = DbType.AnsiString;
802                                 MetaParameter.IsVariableSizeType = true;
803                                 break;
804                         case SqlDbType.TinyInt:
805                                 MetaParameter.TypeName = "tinyint";
806                                 dbType = DbType.Byte;
807                                 break;
808                         case SqlDbType.UniqueIdentifier:
809                                 MetaParameter.TypeName = "uniqueidentifier";
810                                 dbType = DbType.Guid;
811                                 break;
812                         case SqlDbType.Variant:
813                                 MetaParameter.TypeName = "sql_variant";
814                                 dbType = DbType.Object;
815                                 break;
816                         default:
817                                 throw new ArgumentException (exception);
818                         }
819                         sqlDbType = type;
820                 }
821
822                 public override string ToString() 
823                 {
824                         return ParameterName;
825                 }
826
827                 private object SqlTypeToFrameworkType (object value)
828                 {
829                         if (! (value is INullable)) // if the value is not SqlType
830                                 return ConvertToFrameworkType (value);
831
832                         // Map to .net type, as Mono TDS respects only types from .net
833                         switch (value.GetType ().FullName) {
834                         case "System.Data.SqlTypes.SqlBinary":
835                                 return ( (SqlBinary) value).Value;
836                         case "System.Data.SqlTypes.SqlBoolean":
837                                 return ( (SqlBoolean) value).Value;
838                         case "System.Data.SqlTypes.SqlByte":
839                                 return ( (SqlByte) value).Value;
840                         case "System.Data.SqlTypes.SqlDateTime":
841                                 return ( (SqlDateTime) value).Value;
842                         case "System.Data.SqlTypes.SqlDecimal":
843                                 return ( (SqlDecimal) value).Value;
844                         case "System.Data.SqlTypes.SqlDouble":
845                                 return ( (SqlDouble) value).Value;
846                         case "System.Data.SqlTypes.SqlGuid":
847                                 return ( (SqlGuid) value).Value;
848                         case "System.Data.SqlTypes.SqlInt16":
849                                 return ( (SqlInt16) value).Value;
850                         case "System.Data.SqlTypes.SqlInt32 ":
851                                 return ( (SqlInt32 ) value).Value;
852                         case "System.Data.SqlTypes.SqlInt64":
853                                 return ( (SqlInt64) value).Value;
854                         case "System.Data.SqlTypes.SqlMoney":
855                                 return ( (SqlMoney) value).Value;
856                         case "System.Data.SqlTypes.SqlSingle":
857                                 return ( (SqlSingle) value).Value;
858                         case "System.Data.SqlTypes.SqlString":
859                                 return ( (SqlString) value).Value;
860                         }
861                         return value;
862                 }
863
864                 internal object ConvertToFrameworkType (object value)
865                 {
866                         if (value == null || value == DBNull.Value)
867                                 return value;
868                         switch (sqlDbType)  {
869                         case SqlDbType.BigInt :
870                                 return Convert.ChangeType (value, typeof (Int64));
871                         case SqlDbType.Binary:
872                         case SqlDbType.VarBinary:
873                                 if (value is byte[])
874                                         return value;
875                                 break;
876                         case SqlDbType.Bit:
877                                 return Convert.ChangeType (value, typeof (bool));
878                         case SqlDbType.Int:
879                                 return Convert.ChangeType (value, typeof (Int32));
880                         case SqlDbType.SmallInt :
881                                 return Convert.ChangeType (value, typeof (Int16));
882                         case SqlDbType.TinyInt :
883                                 return Convert.ChangeType (value, typeof (byte));
884                         case SqlDbType.Float:
885                                 return Convert.ChangeType (value, typeof (Double));
886                         case SqlDbType.Real:
887                                 return Convert.ChangeType (value, typeof (Single));
888                         case SqlDbType.Decimal:
889                                 return Convert.ChangeType (value, typeof (Decimal));
890                         case SqlDbType.Money:
891                         case SqlDbType.SmallMoney:
892                                 {
893                                         Decimal val = (Decimal)Convert.ChangeType (value, typeof (Decimal));
894                                         return Decimal.Round(val, 4);
895                                 }
896                         case SqlDbType.DateTime:
897                         case SqlDbType.SmallDateTime:
898                                 return Convert.ChangeType (value, typeof (DateTime));
899                         case SqlDbType.VarChar:
900                         case SqlDbType.NVarChar:
901                         case SqlDbType.Char:
902                         case SqlDbType.NChar:
903                         case SqlDbType.Text:
904                         case SqlDbType.NText:
905                                 return Convert.ChangeType (value,  typeof (string));
906                         case SqlDbType.UniqueIdentifier:
907                                 return Convert.ChangeType (value,  typeof (Guid));
908                         case SqlDbType.Variant:
909                                 return metaParameter.Value;
910                         }
911                         throw new  NotImplementedException ("Type Not Supported : " + sqlDbType.ToString());
912                 }
913
914 #if NET_2_0
915                 public override void ResetDbType ()
916                 {
917                         InferSqlType (metaParameter.Value);
918                 }
919
920                 public void ResetSqlDbType ()
921                 {
922                         InferSqlType (metaParameter.Value);
923                 }
924 #endif // NET_2_0
925
926                 #endregion // Methods
927         }
928 }