private void DetermineSqlDbType() { // Determine the SqlDbType SqlDbType type; if (Enum.TryParse(DataTypeName, true, out type)) { SqlDbType = type; } else { switch (DataTypeName) { case "numeric": SqlDbType = SqlDbType.Decimal; break; case "sql_variant": SqlDbType = SqlDbType.Variant; break; case "timestamp": SqlDbType = SqlDbType.VarBinary; break; case "sysname": SqlDbType = SqlDbType.NVarChar; break; default: SqlDbType = DataTypeName.EndsWith(".sys.hierarchyid") ? SqlDbType.NVarChar : SqlDbType.Udt; break; } } }
/// <summary> /// Constructor for a DbColumnWrapper /// </summary> /// <remarks>Most of this logic is taken from SSMS ColumnInfo class</remarks> /// <param name="column">The column we're wrapping around</param> public DbColumnWrapper(DbColumn column) { // Set all the fields for the base AllowDBNull = column.AllowDBNull; BaseCatalogName = column.BaseCatalogName; BaseColumnName = column.BaseColumnName; BaseSchemaName = column.BaseSchemaName; BaseServerName = column.BaseServerName; BaseTableName = column.BaseTableName; ColumnOrdinal = column.ColumnOrdinal; ColumnSize = column.ColumnSize; IsAliased = column.IsAliased; IsAutoIncrement = column.IsAutoIncrement; IsExpression = column.IsExpression; IsHidden = column.IsHidden; IsIdentity = column.IsIdentity; IsKey = column.IsKey; IsLong = column.IsLong; IsReadOnly = column.IsReadOnly; IsUnique = column.IsUnique; NumericPrecision = column.NumericPrecision; NumericScale = column.NumericScale; UdtAssemblyQualifiedName = column.UdtAssemblyQualifiedName; DataType = column.DataType; DataTypeName = column.DataTypeName.ToLowerInvariant(); // Determine the SqlDbType SqlDbType type; if (Enum.TryParse(DataTypeName, true, out type)) { SqlDbType = type; } else { switch (DataTypeName) { case "numeric": SqlDbType = SqlDbType.Decimal; break; case "sql_variant": SqlDbType = SqlDbType.Variant; break; case "timestamp": SqlDbType = SqlDbType.VarBinary; break; case "sysname": SqlDbType = SqlDbType.NVarChar; break; default: SqlDbType = DataTypeName.EndsWith(".sys.hierarchyid") ? SqlDbType.NVarChar : SqlDbType.Udt; break; } } // We want the display name for the column to always exist ColumnName = string.IsNullOrEmpty(column.ColumnName) ? SR.QueryServiceColumnNull : column.ColumnName; switch (DataTypeName) { case "varchar": case "nvarchar": IsChars = true; Debug.Assert(ColumnSize.HasValue); if (ColumnSize.Value == int.MaxValue) { //For Yukon, special case nvarchar(max) with column name == "Microsoft SQL Server 2005 XML Showplan" - //assume it is an XML showplan. //Please note this field must be in sync with a similar field defined in QESQLBatch.cs. //This is not the best fix that we could do but we are trying to minimize code impact //at this point. Post Yukon we should review this code again and avoid //hard-coding special column name in multiple places. const string yukonXmlShowPlanColumn = "Microsoft SQL Server 2005 XML Showplan"; if (column.ColumnName == yukonXmlShowPlanColumn) { // Indicate that this is xml to apply the right size limit // Note we leave chars type as well to use the right retrieval mechanism. IsXml = true; } IsLong = true; } break; case "text": case "ntext": IsChars = true; IsLong = true; break; case "xml": IsXml = true; IsLong = true; break; case "binary": case "image": IsBytes = true; IsLong = true; break; case "varbinary": case "rowversion": IsBytes = true; Debug.Assert(ColumnSize.HasValue); if (ColumnSize.Value == int.MaxValue) { IsLong = true; } break; case "sql_variant": IsSqlVariant = true; break; default: if (!AllServerDataTypes.Contains(DataTypeName)) { // treat all UDT's as long/bytes data types to prevent the CLR from attempting // to load the UDT assembly into our process to call ToString() on the object. IsUdt = true; IsBytes = true; IsLong = true; } break; } if (IsUdt) { // udtassemblyqualifiedname property is used to find if the datatype is of hierarchyid assembly type // Internally hiearchyid is sqlbinary so providerspecific type and type is changed to sqlbinarytype object assemblyQualifiedName = column.UdtAssemblyQualifiedName; const string hierarchyId = "MICROSOFT.SQLSERVER.TYPES.SQLHIERARCHYID"; if (assemblyQualifiedName != null && assemblyQualifiedName.ToString().StartsWith(hierarchyId, StringComparison.OrdinalIgnoreCase)) { DataType = typeof(SqlBinary); } else { DataType = typeof(byte[]); } } else { DataType = column.DataType; } }