// Tim Coleman (tim@timcoleman.com)
// Diego Caravana (diego@toth.it)
// Umadevi S (sumadevi@novell.com)
+// Amit Biswas (amit@amitbiswas.com)
+// Veerapuram Varadhan (vvaradhan@novell.com)
//
// (C) Ximian, Inc. 2002
// Copyright (C) Tim Coleman, 2002
//
//
-// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2004, 2008, 2009 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
using Mono.Data.Tds;
using Mono.Data.Tds.Protocol;
using System;
+using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
using System.Data.SqlTypes;
+using System.Globalization;
using System.Runtime.InteropServices;
using System.Text;
+using System.Xml;
namespace System.Data.SqlClient {
- [TypeConverterAttribute (typeof (SqlParameterConverter))]
-#if NET_2_0
+ [TypeConverterAttribute ("System.Data.SqlClient.SqlParameter+SqlParameterConverter, " + Consts.AssemblySystem_Data)]
public sealed class SqlParameter : DbParameter, IDbDataParameter, IDataParameter, ICloneable
-#else
- public sealed class SqlParameter : MarshalByRefObject, IDbDataParameter, IDataParameter, ICloneable
-#endif // NET_2_0
{
#region Fields
TdsMetaParameter metaParameter;
- SqlParameterCollection container = null;
+ SqlParameterCollection container;
DbType dbType;
ParameterDirection direction = ParameterDirection.Input;
- bool isNullable;
- bool isVariableSizeType = false;
- bool isTypeSet = false;
+ bool isTypeSet;
int offset;
SqlDbType sqlDbType;
string sourceColumn;
DataRowVersion sourceVersion;
+ SqlCompareOptions compareInfo;
+ int localeId;
+ Type sqlType;
+ bool typeChanged;
+ bool sourceColumnNullMapping;
+ string xmlSchemaCollectionDatabase = String.Empty;
+ string xmlSchemaCollectionOwningSchema = String.Empty;
+ string xmlSchemaCollectionName = String.Empty;
+
+ static Hashtable type_mapping;
#endregion // Fields
#region Constructors
+
+ static SqlParameter ()
+ {
+ if (DbTypeMapping == null)
+ DbTypeMapping = new Hashtable ();
+
+ DbTypeMapping.Add (SqlDbType.BigInt, typeof (long));
+ DbTypeMapping.Add (SqlDbType.Bit, typeof (bool));
+ DbTypeMapping.Add (SqlDbType.Char, typeof (string));
+ DbTypeMapping.Add (SqlDbType.NChar, typeof (string));
+ DbTypeMapping.Add (SqlDbType.Text, typeof (string));
+ DbTypeMapping.Add (SqlDbType.NText, typeof (string));
+ DbTypeMapping.Add (SqlDbType.VarChar, typeof (string));
+ DbTypeMapping.Add (SqlDbType.NVarChar, typeof (string));
+ DbTypeMapping.Add (SqlDbType.SmallDateTime, typeof (DateTime));
+ DbTypeMapping.Add (SqlDbType.DateTime, typeof (DateTime));
+ DbTypeMapping.Add (SqlDbType.Decimal, typeof (decimal));
+ DbTypeMapping.Add (SqlDbType.Float, typeof (double));
+ DbTypeMapping.Add (SqlDbType.Binary, typeof (byte []));
+ DbTypeMapping.Add (SqlDbType.Image, typeof (byte []));
+ DbTypeMapping.Add (SqlDbType.Money, typeof (decimal));
+ DbTypeMapping.Add (SqlDbType.SmallMoney, typeof (decimal));
+ DbTypeMapping.Add (SqlDbType.VarBinary, typeof (byte []));
+ DbTypeMapping.Add (SqlDbType.TinyInt, typeof (byte));
+ DbTypeMapping.Add (SqlDbType.Int, typeof (int));
+ DbTypeMapping.Add (SqlDbType.Real, typeof (float));
+ DbTypeMapping.Add (SqlDbType.SmallInt, typeof (short));
+ DbTypeMapping.Add (SqlDbType.UniqueIdentifier, typeof (Guid));
+ DbTypeMapping.Add (SqlDbType.Variant, typeof (object));
+ DbTypeMapping.Add (SqlDbType.Xml, typeof (string));
+
+ type_mapping = new Hashtable ();
+
+ type_mapping.Add (typeof (long), SqlDbType.BigInt);
+ type_mapping.Add (typeof (SqlTypes.SqlInt64), SqlDbType.BigInt);
+
+ type_mapping.Add (typeof (bool), SqlDbType.Bit);
+ type_mapping.Add (typeof (SqlTypes.SqlBoolean), SqlDbType.Bit);
+
+ type_mapping.Add (typeof (char), SqlDbType.NVarChar);
+ type_mapping.Add (typeof (char []), SqlDbType.NVarChar);
+ type_mapping.Add (typeof (SqlTypes.SqlChars), SqlDbType.NVarChar);
+
+ type_mapping.Add (typeof (string), SqlDbType.NVarChar);
+ type_mapping.Add (typeof (SqlTypes.SqlString), SqlDbType.NVarChar);
+
+ type_mapping.Add (typeof (DateTime), SqlDbType.DateTime);
+ type_mapping.Add (typeof (SqlTypes.SqlDateTime), SqlDbType.DateTime);
+
+ type_mapping.Add (typeof (decimal), SqlDbType.Decimal);
+ type_mapping.Add (typeof (SqlTypes.SqlDecimal), SqlDbType.Decimal);
+
+ type_mapping.Add (typeof (double), SqlDbType.Float);
+ type_mapping.Add (typeof (SqlTypes.SqlDouble), SqlDbType.Float);
+
+ type_mapping.Add (typeof (byte []), SqlDbType.VarBinary);
+ type_mapping.Add (typeof (SqlTypes.SqlBinary), SqlDbType.VarBinary);
+
+ type_mapping.Add (typeof (SqlTypes.SqlBytes), SqlDbType.VarBinary);
+
+ type_mapping.Add (typeof (byte), SqlDbType.TinyInt);
+ type_mapping.Add (typeof (SqlTypes.SqlByte), SqlDbType.TinyInt);
+
+ type_mapping.Add (typeof (int), SqlDbType.Int);
+ type_mapping.Add (typeof (SqlTypes.SqlInt32), SqlDbType.Int);
+
+ type_mapping.Add (typeof (float), SqlDbType.Real);
+ type_mapping.Add (typeof (SqlTypes.SqlSingle), SqlDbType.Real);
+
+ type_mapping.Add (typeof (short), SqlDbType.SmallInt);
+ type_mapping.Add (typeof (SqlTypes.SqlInt16), SqlDbType.SmallInt);
+
+ type_mapping.Add (typeof (Guid), SqlDbType.UniqueIdentifier);
+ type_mapping.Add (typeof (SqlTypes.SqlGuid), SqlDbType.UniqueIdentifier);
+
+ type_mapping.Add (typeof (SqlTypes.SqlMoney), SqlDbType.Money);
+
+ type_mapping.Add (typeof (XmlReader), SqlDbType.Xml);
+ type_mapping.Add (typeof (SqlTypes.SqlXml), SqlDbType.Xml);
+
+ type_mapping.Add (typeof (object), SqlDbType.Variant);
+ }
+
public SqlParameter ()
: this (String.Empty, SqlDbType.NVarChar, 0, ParameterDirection.Input, false, 0, 0, String.Empty, DataRowVersion.Current, null)
{
isTypeSet = false;
}
- public SqlParameter (string parameterName, object value)
+ public SqlParameter (string parameterName, object value)
{
- metaParameter = new TdsMetaParameter (parameterName, SqlTypeToFrameworkType (value));
- this.sourceVersion = DataRowVersion.Current;
+ if (parameterName == null)
+ parameterName = string.Empty;
+ metaParameter = new TdsMetaParameter (parameterName, GetFrameworkValue);
+ metaParameter.RawValue = value;
InferSqlType (value);
+ sourceVersion = DataRowVersion.Current;
}
public SqlParameter (string parameterName, SqlDbType dbType)
- : this (parameterName, dbType, 0, ParameterDirection.Input, false, 0, 0, String.Empty, DataRowVersion.Current, null)
+ : this (parameterName, dbType, 0, ParameterDirection.Input, false, 0, 0, null, DataRowVersion.Current, null)
{
}
public SqlParameter (string parameterName, SqlDbType dbType, int size)
- : this (parameterName, dbType, size, ParameterDirection.Input, false, 0, 0, String.Empty, DataRowVersion.Current, null)
+ : this (parameterName, dbType, size, ParameterDirection.Input, false, 0, 0, null, DataRowVersion.Current, null)
{
}
{
}
- [EditorBrowsable (EditorBrowsableState.Advanced)]
+ [EditorBrowsable (EditorBrowsableState.Advanced)]
public SqlParameter (string parameterName, SqlDbType dbType, int size, ParameterDirection direction, bool isNullable, byte precision, byte scale, string sourceColumn, DataRowVersion sourceVersion, object value)
{
+ if (parameterName == null)
+ parameterName = string.Empty;
+
metaParameter = new TdsMetaParameter (parameterName, size,
isNullable, precision,
- scale,
- SqlTypeToFrameworkType (value));
- SqlDbType = dbType;
+ scale,
+ GetFrameworkValue);
+ metaParameter.RawValue = value;
+ if (dbType != SqlDbType.Variant)
+ SqlDbType = dbType;
Direction = direction;
SourceColumn = sourceColumn;
SourceVersion = sourceVersion;
}
+ 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)
+ : this (parameterName, dbType, size, direction, false, precision, scale, sourceColumn, sourceVersion, value)
+ {
+ XmlSchemaCollectionDatabase = xmlSchemaCollectionDatabase;
+ XmlSchemaCollectionOwningSchema = xmlSchemaCollectionOwningSchema;
+ XmlSchemaCollectionName = xmlSchemaCollectionName;
+ SourceColumnNullMapping = sourceColumnNullMapping;
+ }
+
// This constructor is used internally to construct a
// SqlParameter. The value array comes from sp_procedure_params_rowset.
// This is in SqlCommand.DeriveParameters.
+ //
+ // http://social.msdn.microsoft.com/forums/en-US/transactsql/thread/900756fd-3980-48e3-ae59-a15d7fc15b4c/
internal SqlParameter (object[] dbValues)
- : this (dbValues [3].ToString (), String.Empty)
+ : this (dbValues [3].ToString (), (object) null)
{
- Precision = 0;
- Scale = 0;
- Direction = ParameterDirection.Input;
+ ParameterName = (string) dbValues [3];
- ParameterName = (string) dbValues[3];
-
- switch ((short) dbValues[5]) {
+ switch ((short) dbValues [5]) {
case 1:
Direction = ParameterDirection.Input;
break;
case 2:
- Direction = ParameterDirection.Output;
+ Direction = ParameterDirection.InputOutput;
break;
case 3:
- Direction = ParameterDirection.InputOutput;
+ Direction = ParameterDirection.Output;
break;
case 4:
Direction = ParameterDirection.ReturnValue;
break;
- default:
- Direction = ParameterDirection.Input;
- break;
+ default:
+ Direction = ParameterDirection.Input;
+ break;
}
- IsNullable = (dbValues [8] != null &&
- dbValues [8] != DBNull.Value) ? (bool) dbValues [8] : false;
- if (dbValues [12] != null && dbValues [12] != DBNull.Value)
- Precision = (byte) ((short) dbValues [12]);
+ SqlDbType = (SqlDbType) FrameworkDbTypeFromName ((string) dbValues [16]);
- if (dbValues [13] != null && dbValues [13] != DBNull.Value)
- Scale = (byte) ( (short) dbValues [13]);
+ if (MetaParameter.IsVariableSizeType) {
+ if (dbValues [10] != DBNull.Value)
+ Size = (int) dbValues [10];
+ }
- SetDbTypeName ((string) dbValues [16]);
+ if (SqlDbType == SqlDbType.Decimal) {
+ if (dbValues [12] != null && dbValues [12] != DBNull.Value)
+ Precision = (byte) ((short) dbValues [12]);
+ if (dbValues [13] != null && dbValues [13] != DBNull.Value)
+ Scale = (byte) ((short) dbValues [13]);
+ }
}
#endregion // Constructors
if (!isTypeSet)
throw new Exception ("all parameters to have an explicity set type");
- if (isVariableSizeType) {
+ if (MetaParameter.IsVariableSizeType) {
if (SqlDbType == SqlDbType.Decimal && Precision == 0)
throw new Exception ("Parameter of type 'Decimal' have an explicitly set Precision and Scale");
else if (Size == 0)
throw new Exception ("all variable length parameters to have an explicitly set non-zero Size");
}
}
-
-#if ONLY_1_0 || ONLY_1_1
- [Browsable (false)]
- [DataSysDescription ("The parameter generic type.")]
- [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
- [RefreshProperties (RefreshProperties.All)]
-#endif
- [DataCategory ("Data")]
- public
-#if NET_2_0
- override
-#endif // NET_2_0
- DbType DbType {
+
+ public override DbType DbType {
get { return dbType; }
- set {
- SetDbType (value);
+ set {
+ SetDbType (value);
+ typeChanged = true;
isTypeSet = true;
}
}
- [DataCategory ("Data")]
-#if ONLY_1_0 || ONLY_1_1
- [DataSysDescription ("Input, output, or bidirectional parameter.")]
- [DefaultValue (ParameterDirection.Input)]
-#endif
-#if NET_2_0
[RefreshProperties (RefreshProperties.All)]
-#endif
- public
-#if NET_2_0
- override
-#endif // NET_2_0
- ParameterDirection Direction {
+ public override
+ ParameterDirection Direction {
get { return direction; }
set {
direction = value;
switch( direction ) {
case ParameterDirection.Output:
- MetaParameter.Direction = TdsParameterDirection.Output;
+ MetaParameter.Direction = TdsParameterDirection.Output;
break;
case ParameterDirection.InputOutput:
MetaParameter.Direction = TdsParameterDirection.InputOutput;
get { return metaParameter; }
}
-#if ONLY_1_0 || ONLY_1_1
- [Browsable (false)]
- [DataSysDescription ("a design-time property used for strongly typed code-generation.")]
- [DefaultValue (false)]
- [DesignOnly (true)]
- [EditorBrowsable (EditorBrowsableState.Advanced)]
-#endif
- public
-#if NET_2_0
- override
-#endif // NET_2_0
- bool IsNullable {
+ public override bool IsNullable {
get { return metaParameter.IsNullable; }
set { metaParameter.IsNullable = value; }
}
[Browsable (false)]
- [DataCategory ("Data")]
-#if ONLY_1_0 || ONLY_1_1
- [DataSysDescription ("Offset in variable length data types.")]
- [DefaultValue (0)]
-#endif
-#if NET_2_0
[EditorBrowsable (EditorBrowsableState.Advanced)]
-#endif
public int Offset {
get { return offset; }
set { offset = value; }
}
-#if ONLY_1_0 || ONLY_1_1
- [DataSysDescription ("Name of the parameter, like '@p1'")]
- [DefaultValue ("")]
-#endif
- public
-#if NET_2_0
- override
-#endif // NET_2_0
- string ParameterName {
+ public override string ParameterName {
get { return metaParameter.ParameterName; }
- set { metaParameter.ParameterName = value; }
+ set {
+ if (value == null)
+ value = string.Empty;
+ metaParameter.ParameterName = value;
+ }
}
- [DataCategory ("Data")]
-#if ONLY_1_0 || ONLY_1_1
- [DataSysDescription ("For decimal, numeric, varnumeric DBTypes.")]
[DefaultValue (0)]
-#endif
-#if NET_2_0
- [Browsable (false)]
- [EditorBrowsable (EditorBrowsableState.Never)]
-#endif
public byte Precision {
get { return metaParameter.Precision; }
set { metaParameter.Precision = value; }
}
- [DataCategory ("Data")]
-#if ONLY_1_0 || ONLY_1_1
- [DataSysDescription ("For decimal, numeric, varnumeric DBTypes.")]
[DefaultValue (0)]
-#endif
-#if NET_2_0
- [Browsable (false)]
- [EditorBrowsable (EditorBrowsableState.Never)]
-#endif
- public byte Scale {
+ public byte Scale {
get { return metaParameter.Scale; }
set { metaParameter.Scale = value; }
}
- [DataCategory ("Data")]
-#if ONLY_1_0 || ONLY_1_1
- [DataSysDescription ("Size of variable length data types (string & arrays).")]
- [DefaultValue (0)]
-#endif
- public
-#if NET_2_0
- override
-#endif // NET_2_0
- int Size {
+ public override int Size {
get { return metaParameter.Size; }
set { metaParameter.Size = value; }
}
- [DataCategory ("Data")]
-#if ONLY_1_0 || ONLY_1_1
- [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.")]
- [DefaultValue ("")]
-#endif
- public
-#if NET_2_0
- override
-#endif // NET_2_0
- string SourceColumn {
- get { return sourceColumn; }
+ public override string SourceColumn {
+ get {
+ if (sourceColumn == null)
+ return string.Empty;
+ return sourceColumn;
+ }
set { sourceColumn = value; }
}
- [DataCategory ("Data")]
-#if ONLY_1_0 || ONLY_1_1
- [DataSysDescription ("When used by a DataAdapter.Update (UpdateCommand only), the version of the DataRow value that is used to update the data source.")]
- [DefaultValue (DataRowVersion.Current)]
-#endif
- public
-#if NET_2_0
- override
-#endif // NET_2_0
- DataRowVersion SourceVersion {
+ public override DataRowVersion SourceVersion {
get { return sourceVersion; }
set { sourceVersion = value; }
}
- [DataCategory ("Data")]
-#if ONLY_1_0 || ONLY_1_1
- [DataSysDescription ("The parameter native type.")]
- [DefaultValue (SqlDbType.NVarChar)]
-#endif
[RefreshProperties (RefreshProperties.All)]
-#if NET_2_0
[DbProviderSpecificTypeProperty(true)]
-#endif
public SqlDbType SqlDbType {
get { return sqlDbType; }
- set {
- SetSqlDbType (value);
+ set {
+ SetSqlDbType (value);
+ typeChanged = true;
isTypeSet = true;
}
}
- [DataCategory ("Data")]
-#if ONLY_1_0 || ONLY_1_1
- [DataSysDescription ("Value of the parameter.")]
- [DefaultValue (null)]
-#endif
- [TypeConverterAttribute (typeof (StringConverter))]
-#if NET_2_0
- [RefreshProperties (RefreshProperties.All)]
-#endif
- public
-#if NET_2_0
- override
-#endif // NET_2_0
- object Value {
- get { return metaParameter.Value; }
- set {
- if (!isTypeSet)
+ [TypeConverterAttribute (typeof (StringConverter))]
+ [RefreshProperties (RefreshProperties.All)]
+ public override object Value {
+ get {
+ if (sqlType != null)
+ return GetSqlValue (metaParameter.RawValue);
+ return metaParameter.RawValue;
+ }
+ set {
+ if (!isTypeSet) {
InferSqlType (value);
- metaParameter.Value = SqlTypeToFrameworkType (value);
+ }
+
+ if (value is INullable) {
+ sqlType = value.GetType ();
+ value = SqlTypeToFrameworkType (value);
+ }
+ metaParameter.RawValue = value;
}
}
-//#if NET_2_0
-// public SqlCompareOptions CompareInfo{
+ [Browsable (false)]
+ public SqlCompareOptions CompareInfo{
+ get{ return compareInfo; }
+ set{ compareInfo = value; }
+ }
+
+ [Browsable (false)]
+ public int LocaleId {
+ get { return localeId; }
+ set { localeId = value; }
+ }
-//#endif
-#if NET_2_0
+ [Browsable (false)]
+ [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+ public Object SqlValue {
+ get {
+ return GetSqlValue (metaParameter.RawValue);
+ }
+ set {
+ Value = value;
+ }
+ }
+
public override bool SourceColumnNullMapping {
- get { return false ; }
- set { }
+ get { return sourceColumnNullMapping; }
+ set { sourceColumnNullMapping = value; }
+ }
+
+ public string XmlSchemaCollectionDatabase {
+ get { return xmlSchemaCollectionDatabase; }
+ set { xmlSchemaCollectionDatabase = (value == null ? String.Empty : value); }
+ }
+
+ public string XmlSchemaCollectionName {
+ get { return xmlSchemaCollectionName; }
+ set {
+ xmlSchemaCollectionName = (value == null ? String.Empty : value);
+ }
+ }
+
+ public string XmlSchemaCollectionOwningSchema {
+ get { return xmlSchemaCollectionOwningSchema; }
+ set {
+ xmlSchemaCollectionOwningSchema = (value == null ? String.Empty : value);
+ }
}
-#endif
+
+ [BrowsableAttribute(false)]
+ public string UdtTypeName { get; set; }
#endregion // Properties
// If the value is set without the DbType/SqlDbType being set, then we
// infer type information.
- private void InferSqlType (object value)
+ void InferSqlType (object value)
{
- if (value == null || value == DBNull.Value)
+ if (value == null || value == DBNull.Value) {
+ SetSqlDbType (SqlDbType.NVarChar);
return;
+ }
Type type = value.GetType ();
+ if (type.IsEnum)
+ type = Enum.GetUnderlyingType (type);
+ object t = type_mapping [type];
+ if (t == null)
+ throw new ArgumentException (String.Format ("The parameter data type of {0} is invalid.", type.FullName));
+ SetSqlDbType ((SqlDbType) t);
+ }
+
+ // Returns System.Type corresponding to the underlying SqlDbType
+ internal override Type SystemType {
+ get {
+ return (Type) DbTypeMapping [sqlDbType];
+ }
+ }
- string exception = String.Format ("The parameter data type of {0} is invalid.", type.Name);
+ internal override object FrameworkDbType {
+ get {
+ return sqlDbType;
+ }
+
+ set {
+ object t;
+ try {
+ t = (DbType) DbTypeFromName ((string)value);
+ SetDbType ((DbType)t);
+ } catch (ArgumentException) {
+ t = (SqlDbType)FrameworkDbTypeFromName ((string)value);
+ SetSqlDbType ((SqlDbType) t);
+ }
+ }
+ }
- switch (type.FullName) {
- case "System.Int64":
- case "System.Data.SqlTypes.SqlInt64":
- SetSqlDbType (SqlDbType.BigInt);
- break;
- case "System.Boolean":
- case "System.Data.SqlTypes.SqlBoolean":
- SetSqlDbType (SqlDbType.Bit);
- break;
- case "System.String":
- case "System.Data.SqlTypes.SqlString":
- SetSqlDbType (SqlDbType.NVarChar);
- break;
- case "System.DateTime":
- case "System.Data.SqlTypes.SqlDateTime":
- SetSqlDbType (SqlDbType.DateTime);
- break;
- case "System.Decimal":
- case "System.Data.SqlTypes.SqlDecimal":
- SetSqlDbType (SqlDbType.Decimal);
- break;
- case "System.Double":
- case "System.Data.SqlTypes.SqlDouble":
- SetSqlDbType (SqlDbType.Float);
- break;
- case "System.Byte[]":
- case "System.Data.SqlTypes.SqlBinary":
- SetSqlDbType (SqlDbType.VarBinary);
- break;
- case "System.Byte":
- case "System.Data.SqlTypes.SqlByte":
- SetSqlDbType (SqlDbType.TinyInt);
- break;
- case "System.Int32":
- case "System.Data.SqlTypes.SqlInt32":
- SetSqlDbType (SqlDbType.Int);
- break;
- case "System.Single":
- case "System.Data.SqlTypes.Single":
- SetSqlDbType (SqlDbType.Real);
- break;
- case "System.Int16":
- case "System.Data.SqlTypes.SqlInt16":
- SetSqlDbType (SqlDbType.SmallInt);
- break;
- case "System.Guid":
- case "System.Data.SqlTypes.SqlGuid":
- SetSqlDbType (SqlDbType.UniqueIdentifier);
- break;
- case "System.Money":
- case "System.SmallMoney":
- case "System.Data.SqlTypes.SqlMoney":
- SetSqlDbType (SqlDbType.Money);
- break;
- case "System.Object":
- SetSqlDbType (SqlDbType.Variant);
- break;
- default:
- throw new ArgumentException (exception);
+ DbType DbTypeFromName (string name)
+ {
+ switch (name.ToLower ()) {
+ case "ansistring":
+ return DbType.AnsiString;
+ case "ansistringfixedlength":
+ return DbType.AnsiStringFixedLength;
+ case "binary":
+ return DbType.Binary;
+ case "boolean":
+ return DbType.Boolean;
+ case "byte":
+ return DbType.Byte;
+ case "currency":
+ return DbType.Currency;
+ case "date":
+ return DbType.Date;
+ case "datetime":
+ return DbType.DateTime;
+ case "decimal":
+ return DbType.Decimal;
+ case "double":
+ return DbType.Double;
+ case "guid":
+ return DbType.Guid;
+ case "int16":
+ return DbType.Int16;
+ case "int32":
+ return DbType.Int32;
+ case "int64":
+ return DbType.Int64;
+ case "object":
+ return DbType.Object;
+ case "single":
+ return DbType.Single;
+ case "string":
+ return DbType.String;
+ case "stringfixedlength":
+ return DbType.StringFixedLength;
+ case "time":
+ return DbType.Time;
+ case "xml":
+ return DbType.Xml;
+ default:
+ string exception = String.Format ("No mapping exists from {0} to a known DbType.", name);
+ throw new ArgumentException (exception);
}
}
// to an SqlDbType, throw an exception.
private void SetDbType (DbType type)
{
- string exception = String.Format ("No mapping exists from DbType {0} to a known SqlDbType.", type);
-
switch (type) {
case DbType.AnsiString:
MetaParameter.TypeName = "varchar";
sqlDbType = SqlDbType.VarChar;
- isVariableSizeType = true;
+ MetaParameter.IsVariableSizeType = true;
break;
case DbType.AnsiStringFixedLength:
MetaParameter.TypeName = "char";
sqlDbType = SqlDbType.Char;
- isVariableSizeType = true;
+ MetaParameter.IsVariableSizeType = true;
break;
case DbType.Binary:
MetaParameter.TypeName = "varbinary";
sqlDbType = SqlDbType.VarBinary;
- isVariableSizeType = true;
+ MetaParameter.IsVariableSizeType = true;
break;
case DbType.Boolean:
MetaParameter.TypeName = "bit";
MetaParameter.TypeName = "datetime";
sqlDbType = SqlDbType.DateTime;
break;
+ case DbType.DateTime2:
+ MetaParameter.TypeName = "datetime2";
+ sqlDbType = SqlDbType.DateTime2;
+ break;
case DbType.Decimal:
MetaParameter.TypeName = "decimal";
sqlDbType = SqlDbType.Decimal;
case DbType.String:
MetaParameter.TypeName = "nvarchar";
sqlDbType = SqlDbType.NVarChar;
- isVariableSizeType = true;
+ MetaParameter.IsVariableSizeType = true;
break;
case DbType.StringFixedLength:
MetaParameter.TypeName = "nchar";
sqlDbType = SqlDbType.NChar;
- isVariableSizeType = true;
+ MetaParameter.IsVariableSizeType = true;
break;
case DbType.Time:
MetaParameter.TypeName = "datetime";
sqlDbType = SqlDbType.DateTime;
break;
+ // Handle Xml type as string
+ case DbType.Xml:
+ MetaParameter.TypeName = "xml";
+ sqlDbType = SqlDbType.Xml;
+ MetaParameter.IsVariableSizeType = true;
+ break;
default:
+ string exception = String.Format ("No mapping exists from DbType {0} to a known SqlDbType.", type);
throw new ArgumentException (exception);
}
dbType = type;
}
// Used by internal constructor which has a SQL Server typename
- private void SetDbTypeName (string dbTypeName)
+ private SqlDbType FrameworkDbTypeFromName (string dbTypeName)
{
switch (dbTypeName.ToLower ()) {
case "bigint":
- SqlDbType = SqlDbType.BigInt;
- break;
+ return SqlDbType.BigInt;
case "binary":
- SqlDbType = SqlDbType.Binary;
- break;
+ return SqlDbType.Binary;
case "bit":
- SqlDbType = SqlDbType.Bit;
- break;
+ return SqlDbType.Bit;
case "char":
- SqlDbType = SqlDbType.Char;
- break;
+ return SqlDbType.Char;
case "datetime":
- SqlDbType = SqlDbType.DateTime;
- break;
+ return SqlDbType.DateTime;
case "decimal":
- SqlDbType = SqlDbType.Decimal;
- break;
+ return SqlDbType.Decimal;
case "float":
- SqlDbType = SqlDbType.Float;
- break;
+ return SqlDbType.Float;
case "image":
- SqlDbType = SqlDbType.Image;
- break;
+ return SqlDbType.Image;
case "int":
- SqlDbType = SqlDbType.Int;
- break;
+ return SqlDbType.Int;
case "money":
- SqlDbType = SqlDbType.Money;
- break;
+ return SqlDbType.Money;
case "nchar":
- SqlDbType = SqlDbType.NChar;
- break;
+ return SqlDbType.NChar;
case "ntext":
- SqlDbType = SqlDbType.NText;
- break;
+ return SqlDbType.NText;
case "nvarchar":
- SqlDbType = SqlDbType.NVarChar;
- break;
+ return SqlDbType.NVarChar;
case "real":
- SqlDbType = SqlDbType.Real;
- break;
+ return SqlDbType.Real;
case "smalldatetime":
- SqlDbType = SqlDbType.SmallDateTime;
- break;
+ return SqlDbType.SmallDateTime;
case "smallint":
- SqlDbType = SqlDbType.SmallInt;
- break;
+ return SqlDbType.SmallInt;
case "smallmoney":
- SqlDbType = SqlDbType.SmallMoney;
- break;
+ return SqlDbType.SmallMoney;
case "text":
- SqlDbType = SqlDbType.Text;
- break;
+ return SqlDbType.Text;
case "timestamp":
- SqlDbType = SqlDbType.Timestamp;
- break;
+ return SqlDbType.Timestamp;
case "tinyint":
- SqlDbType = SqlDbType.TinyInt;
- break;
+ return SqlDbType.TinyInt;
case "uniqueidentifier":
- SqlDbType = SqlDbType.UniqueIdentifier;
- break;
+ return SqlDbType.UniqueIdentifier;
case "varbinary":
- SqlDbType = SqlDbType.VarBinary;
- break;
+ return SqlDbType.VarBinary;
case "varchar":
- SqlDbType = SqlDbType.VarChar;
- break;
+ return SqlDbType.VarChar;
+ case "sql_variant":
+ return SqlDbType.Variant;
+ case "xml":
+ return SqlDbType.Xml;
default:
- SqlDbType = SqlDbType.Variant;
- break;
+ return SqlDbType.Variant;
}
}
// When the SqlDbType is set, we also set the DbType, as well as the SQL Server
// string representation of the type name. If the SqlDbType is not convertible
// to a DbType, throw an exception.
- private void SetSqlDbType (SqlDbType type)
+ internal void SetSqlDbType (SqlDbType type)
{
- string exception = String.Format ("No mapping exists from SqlDbType {0} to a known DbType.", type);
-
switch (type) {
case SqlDbType.BigInt:
MetaParameter.TypeName = "bigint";
case SqlDbType.Binary:
MetaParameter.TypeName = "binary";
dbType = DbType.Binary;
- isVariableSizeType = true;
+ MetaParameter.IsVariableSizeType = true;
break;
case SqlDbType.Timestamp:
MetaParameter.TypeName = "timestamp";
case SqlDbType.VarBinary:
MetaParameter.TypeName = "varbinary";
dbType = DbType.Binary;
- isVariableSizeType = true;
+ MetaParameter.IsVariableSizeType = true;
break;
case SqlDbType.Bit:
MetaParameter.TypeName = "bit";
case SqlDbType.Char:
MetaParameter.TypeName = "char";
dbType = DbType.AnsiStringFixedLength;
- isVariableSizeType = true;
+ MetaParameter.IsVariableSizeType = true;
break;
case SqlDbType.DateTime:
MetaParameter.TypeName = "datetime";
case SqlDbType.Image:
MetaParameter.TypeName = "image";
dbType = DbType.Binary;
- isVariableSizeType = true;
+ MetaParameter.IsVariableSizeType = true;
break;
case SqlDbType.Int:
MetaParameter.TypeName = "int";
case SqlDbType.NChar:
MetaParameter.TypeName = "nchar";
dbType = DbType.StringFixedLength;
- isVariableSizeType = true;
+ MetaParameter.IsVariableSizeType = true;
break;
case SqlDbType.NText:
MetaParameter.TypeName = "ntext";
dbType = DbType.String;
- isVariableSizeType = true;
+ MetaParameter.IsVariableSizeType = true;
break;
case SqlDbType.NVarChar:
MetaParameter.TypeName = "nvarchar";
dbType = DbType.String;
- isVariableSizeType = true;
+ MetaParameter.IsVariableSizeType = true;
break;
case SqlDbType.Real:
MetaParameter.TypeName = "real";
case SqlDbType.Text:
MetaParameter.TypeName = "text";
dbType = DbType.AnsiString;
- isVariableSizeType = true;
+ MetaParameter.IsVariableSizeType = true;
break;
case SqlDbType.VarChar:
MetaParameter.TypeName = "varchar";
dbType = DbType.AnsiString;
- isVariableSizeType = true;
+ MetaParameter.IsVariableSizeType = true;
break;
case SqlDbType.TinyInt:
MetaParameter.TypeName = "tinyint";
MetaParameter.TypeName = "sql_variant";
dbType = DbType.Object;
break;
+ case SqlDbType.Xml:
+ MetaParameter.TypeName = "xml";
+ dbType = DbType.Xml;
+ MetaParameter.IsVariableSizeType = true;
+ break;
default:
- throw new ArgumentException (exception);
+ string exception = String.Format ("No mapping exists from SqlDbType {0} to a known DbType.", type);
+ throw new ArgumentOutOfRangeException ("SqlDbType", exception);
}
sqlDbType = type;
}
return ParameterName;
}
- private object SqlTypeToFrameworkType (object value)
+ object GetFrameworkValue (object rawValue, ref bool updated)
{
- if (! (value is INullable)) // if the value is not SqlType
+ object tdsValue;
+
+ updated = typeChanged || updated;
+ if (updated) {
+ tdsValue = SqlTypeToFrameworkType (rawValue);
+ typeChanged = false;
+ } else
+ tdsValue = null;
+ return tdsValue;
+ }
+
+ // TODO: Code copied from SqlDataReader, need a better approach
+ object GetSqlValue (object value)
+ {
+ if (value == null)
return value;
+ switch (sqlDbType) {
+ case SqlDbType.BigInt:
+ if (value == DBNull.Value)
+ return SqlInt64.Null;
+ return (SqlInt64) ((long) value);
+ case SqlDbType.Binary:
+ case SqlDbType.Image:
+ case SqlDbType.VarBinary:
+ case SqlDbType.Timestamp:
+ if (value == DBNull.Value)
+ return SqlBinary.Null;
+ return (SqlBinary) (byte[]) value;
+ case SqlDbType.Bit:
+ if (value == DBNull.Value)
+ return SqlBoolean.Null;
+ return (SqlBoolean) ((bool) value);
+ case SqlDbType.Char:
+ case SqlDbType.NChar:
+ case SqlDbType.NText:
+ case SqlDbType.NVarChar:
+ case SqlDbType.Text:
+ case SqlDbType.VarChar:
+ if (value == DBNull.Value)
+ return SqlString.Null;
+
+ string str;
+ Type type = value.GetType ();
+ if (type == typeof (char))
+ str = value.ToString ();
+ else if (type == typeof (char[]))
+ str = new String ((char[])value);
+ else
+ str = ((string)value);
+ return (SqlString) str;
+ case SqlDbType.DateTime:
+ case SqlDbType.SmallDateTime:
+ if (value == DBNull.Value)
+ return SqlDateTime.Null;
+ return (SqlDateTime) ((DateTime) value);
+ case SqlDbType.Decimal:
+ if (value == DBNull.Value)
+ return SqlDecimal.Null;
+ if (value is TdsBigDecimal)
+ return SqlDecimal.FromTdsBigDecimal ((TdsBigDecimal) value);
+ return (SqlDecimal) ((decimal) value);
+ case SqlDbType.Float:
+ if (value == DBNull.Value)
+ return SqlDouble.Null;
+ return (SqlDouble) ((double) value);
+ case SqlDbType.Int:
+ if (value == DBNull.Value)
+ return SqlInt32.Null;
+ return (SqlInt32) ((int) value);
+ case SqlDbType.Money:
+ case SqlDbType.SmallMoney:
+ if (value == DBNull.Value)
+ return SqlMoney.Null;
+ return (SqlMoney) ((decimal) value);
+ case SqlDbType.Real:
+ if (value == DBNull.Value)
+ return SqlSingle.Null;
+ return (SqlSingle) ((float) value);
+ case SqlDbType.UniqueIdentifier:
+ if (value == DBNull.Value)
+ return SqlGuid.Null;
+ return (SqlGuid) ((Guid) value);
+ case SqlDbType.SmallInt:
+ if (value == DBNull.Value)
+ return SqlInt16.Null;
+ return (SqlInt16) ((short) value);
+ case SqlDbType.TinyInt:
+ if (value == DBNull.Value)
+ return SqlByte.Null;
+ return (SqlByte) ((byte) value);
+ case SqlDbType.Xml:
+ if (value == DBNull.Value)
+ return SqlXml.Null;
+ return (SqlXml) value;
+ default:
+ throw new NotImplementedException ("Type '" + sqlDbType + "' not implemented.");
+ }
+ }
+
+ object SqlTypeToFrameworkType (object value)
+ {
+ INullable nullable = value as INullable;
+ if (nullable == null)
+ return ConvertToFrameworkType (value);
+ if (nullable.IsNull)
+ return DBNull.Value;
+
+ Type type = value.GetType ();
// Map to .net type, as Mono TDS respects only types from .net
- switch (value.GetType ().FullName) {
- case "System.Data.SqlTypes.SqlBinary":
- return ( (SqlBinary) value).Value;
- case "System.Data.SqlTypes.SqlBoolean":
- return ( (SqlBoolean) value).Value;
- case "System.Data.SqlTypes.SqlByte":
- return ( (SqlByte) value).Value;
- case "System.Data.SqlTypes.SqlDateTime":
- return ( (SqlDateTime) value).Value;
- case "System.Data.SqlTypes.SqlDecimal":
- return ( (SqlDecimal) value).Value;
- case "System.Data.SqlTypes.SqlDouble":
- return ( (SqlDouble) value).Value;
- case "System.Data.SqlTypes.SqlGuid":
- return ( (SqlGuid) value).Value;
- case "System.Data.SqlTypes.SqlInt16":
- return ( (SqlInt16) value).Value;
- case "System.Data.SqlTypes.SqlInt32 ":
- return ( (SqlInt32 ) value).Value;
- case "System.Data.SqlTypes.SqlInt64":
- return ( (SqlInt64) value).Value;
- case "System.Data.SqlTypes.SqlMoney":
- return ( (SqlMoney) value).Value;
- case "System.Data.SqlTypes.SqlSingle":
- return ( (SqlSingle) value).Value;
- case "System.Data.SqlTypes.SqlString":
- return ( (SqlString) value).Value;
+
+ if (typeof (SqlString) == type) {
+ return ((SqlString) value).Value;
+ }
+
+ if (typeof (SqlInt16) == type) {
+ return ((SqlInt16) value).Value;
+ }
+
+ if (typeof (SqlInt32) == type) {
+ return ((SqlInt32) value).Value;
+ }
+
+ if (typeof (SqlDateTime) == type) {
+ return ((SqlDateTime) value).Value;
+ }
+
+ if (typeof (SqlInt64) == type) {
+ return ((SqlInt64) value).Value;
+ }
+
+ if (typeof (SqlBinary) == type) {
+ return ((SqlBinary) value).Value;
+ }
+
+ if (typeof (SqlBytes) == type) {
+ return ((SqlBytes) value).Value;
+ }
+
+ if (typeof (SqlChars) == type) {
+ return ((SqlChars) value).Value;
+ }
+
+ if (typeof (SqlBoolean) == type) {
+ return ((SqlBoolean) value).Value;
+ }
+
+ if (typeof (SqlByte) == type) {
+ return ((SqlByte) value).Value;
+ }
+
+ if (typeof (SqlDecimal) == type) {
+ return ((SqlDecimal) value).Value;
+ }
+
+ if (typeof (SqlDouble) == type) {
+ return ((SqlDouble) value).Value;
+ }
+
+ if (typeof (SqlGuid) == type) {
+ return ((SqlGuid) value).Value;
+ }
+
+ if (typeof (SqlMoney) == type) {
+ return ((SqlMoney) value).Value;
}
+
+ if (typeof (SqlSingle) == type) {
+ return ((SqlSingle) value).Value;
+ }
+
return value;
}
-#if NET_2_0
- [MonoTODO]
- public override void ResetDbType ()
- {
- throw new NotImplementedException ();
- }
-#endif // NET_2_0
+ internal object ConvertToFrameworkType (object value)
+ {
+ if (value == null || value == DBNull.Value)
+ return value;
+ if (sqlDbType == SqlDbType.Variant)
+ return metaParameter.Value;
+
+ Type frameworkType = SystemType;
+ if (frameworkType == null)
+ throw new NotImplementedException ("Type Not Supported : " + sqlDbType.ToString());
+
+ Type valueType = value.GetType ();
+ if (valueType == frameworkType)
+ return value;
+
+ object sqlvalue = null;
+
+ try {
+ sqlvalue = ConvertToFrameworkType (value, frameworkType);
+ } catch (FormatException ex) {
+ throw new FormatException (string.Format (CultureInfo.InvariantCulture,
+ "Parameter value could not be converted from {0} to {1}.",
+ valueType.Name, frameworkType.Name), ex);
+ }
+
+ return sqlvalue;
+ }
+
+ object ConvertToFrameworkType (object value, Type frameworkType)
+ {
+ object sqlvalue = Convert.ChangeType (value, frameworkType);
+ switch (sqlDbType) {
+ case SqlDbType.Money:
+ case SqlDbType.SmallMoney:
+ sqlvalue = Decimal.Round ((decimal) sqlvalue, 4);
+ break;
+ }
+ return sqlvalue;
+ }
+
+ public override void ResetDbType ()
+ {
+ InferSqlType (Value);
+ }
+
+ public void ResetSqlDbType ()
+ {
+ InferSqlType (Value);
+ }
#endregion // Methods
}