public override Type GetFieldType(int i) { return(RowData.DeriveSystemType(m_scheme.RequireField(i).DataType)); }
/// <summary> /// Returns a <see cref="T:System.Data.DataTable"/> that describes the column metadata of the <see cref="T:System.Data.IDataReader"/>. /// </summary> /// <returns> /// A <see cref="T:System.Data.DataTable"/> that describes the column metadata. /// </returns> /// <exception cref="T:System.InvalidOperationException">The <see cref="T:System.Data.IDataReader"/> is closed. </exception> /// <filterpriority>2</filterpriority> public override DataTable GetSchemaTable() { var dataTable = new DataTable("SchemaTable") { Locale = CultureInfo.InvariantCulture, MinimumCapacity = m_scheme.FieldCount }; var cColumnName = new DataColumn(SchemaTableColumn.ColumnName, typeof(string)); var cColumnOrdinal = new DataColumn(SchemaTableColumn.ColumnOrdinal, typeof(int)); var cColumnSize = new DataColumn(SchemaTableColumn.ColumnSize, typeof(int)); var cNumericPrecision = new DataColumn(SchemaTableColumn.NumericPrecision, typeof(short)); var cNumericScale = new DataColumn(SchemaTableColumn.NumericScale, typeof(short)); var cDataType = new DataColumn(SchemaTableColumn.DataType, typeof(Type)); var cProviderSpecificDataType = new DataColumn(SchemaTableOptionalColumn.ProviderSpecificDataType, typeof(Type)); var cNonVersionedProviderType = new DataColumn(SchemaTableColumn.NonVersionedProviderType, typeof(int)); var cProviderType = new DataColumn(SchemaTableColumn.ProviderType, typeof(int)); var cIsLong = new DataColumn(SchemaTableColumn.IsLong, typeof(bool)); var cAllowDbNull = new DataColumn(SchemaTableColumn.AllowDBNull, typeof(bool)); var cIsReadOnly = new DataColumn(SchemaTableOptionalColumn.IsReadOnly, typeof(bool)); var cIsRowVersion = new DataColumn(SchemaTableOptionalColumn.IsRowVersion, typeof(bool)); var sIsUnique = new DataColumn(SchemaTableColumn.IsUnique, typeof(bool)); var sIsKey = new DataColumn(SchemaTableColumn.IsKey, typeof(bool)); var cIsAutoIncrement = new DataColumn(SchemaTableOptionalColumn.IsAutoIncrement, typeof(bool)); var sIsHidden = new DataColumn(SchemaTableOptionalColumn.IsHidden, typeof(bool)); var cBaseCatalogName = new DataColumn(SchemaTableOptionalColumn.BaseCatalogName, typeof(string)); var cBaseSchemaName = new DataColumn(SchemaTableColumn.BaseSchemaName, typeof(string)); var cBaseTableName = new DataColumn(SchemaTableColumn.BaseTableName, typeof(string)); var cBaseColumnName = new DataColumn(SchemaTableColumn.BaseColumnName, typeof(string)); var cBaseServerName = new DataColumn(SchemaTableOptionalColumn.BaseServerName, typeof(string)); var cIsAliased = new DataColumn(SchemaTableColumn.IsAliased, typeof(bool)); var sIsExpression = new DataColumn(SchemaTableColumn.IsExpression, typeof(bool)); var cIsIdentity = new DataColumn("IsIdentity", typeof(bool)); var cDataTypeName = new DataColumn("DataTypeName", typeof(string)); var cUdtAssemblyQualifiedName = new DataColumn("UdtAssemblyQualifiedName", typeof(string)); var cXmlSchemaCollectionDatabase = new DataColumn("XmlSchemaCollectionDatabase", typeof(string)); var cXmlSchemaCollectionOwningSchema = new DataColumn("XmlSchemaCollectionOwningSchema", typeof(string)); var cXmlSchemaCollectionName = new DataColumn("XmlSchemaCollectionName", typeof(string)); var cIsColumnSet = new DataColumn("IsColumnSet", typeof(bool)); cColumnOrdinal.DefaultValue = 0; cIsLong.DefaultValue = false; var columns = dataTable.Columns; columns.Add(cColumnName); columns.Add(cColumnOrdinal); columns.Add(cColumnSize); columns.Add(cNumericPrecision); columns.Add(cNumericScale); columns.Add(sIsUnique); columns.Add(sIsKey); columns.Add(cBaseServerName); columns.Add(cBaseCatalogName); columns.Add(cBaseColumnName); columns.Add(cBaseSchemaName); columns.Add(cBaseTableName); columns.Add(cDataType); columns.Add(cAllowDbNull); columns.Add(cProviderType); columns.Add(cIsAliased); columns.Add(sIsExpression); columns.Add(cIsIdentity); columns.Add(cIsAutoIncrement); columns.Add(cIsRowVersion); columns.Add(sIsHidden); columns.Add(cIsLong); columns.Add(cIsReadOnly); columns.Add(cProviderSpecificDataType); columns.Add(cDataTypeName); columns.Add(cXmlSchemaCollectionDatabase); columns.Add(cXmlSchemaCollectionOwningSchema); columns.Add(cXmlSchemaCollectionName); columns.Add(cUdtAssemblyQualifiedName); columns.Add(cNonVersionedProviderType); columns.Add(cIsColumnSet); foreach (var field in m_scheme.Fields) { var systemType = RowData.DeriveSystemType(field.DataType); var row = dataTable.NewRow(); row[cColumnName] = field.Name; row[cColumnOrdinal] = field.Ordinal; row[cColumnSize] = 0; row[cDataType] = systemType; row[cProviderSpecificDataType] = systemType; row[cNonVersionedProviderType] = field.DataType; row[cDataTypeName] = GetDataTypeName(field.Ordinal); row[cProviderType] = field.DataType; row[cNumericPrecision] = DBNull.Value; row[cNumericScale] = DBNull.Value; row[cAllowDbNull] = true; row[cIsAliased] = false; row[sIsKey] = false; row[sIsHidden] = false; row[sIsExpression] = false; row[cIsIdentity] = false; row[cIsAutoIncrement] = false; row[cIsLong] = false; row[sIsUnique] = false; row[cIsRowVersion] = false; row[cIsReadOnly] = false; row[cIsColumnSet] = false; dataTable.Rows.Add(row); row.AcceptChanges(); } foreach (DataColumn dataColumn in columns) { dataColumn.ReadOnly = true; } return(dataTable); }
/// <summary> /// Validates consistency of configuration values on this parameter instance. /// </summary> public void Validate() { IsValidatedCollection = false; if (Direction != ParameterDirection.Input) { throw new DataException("Direction must be set to " + ParameterDirection.Input); } if (string.IsNullOrEmpty(ParameterName)) { throw new DataException("ParameterName is null or empty"); } if (ParameterName.Length < 2 || ParameterName[0] != '@') { throw new DataException("ParameterName must have at least two characters and start with '@'"); } for (var index = 1; index < ParameterName.Length; index++) { var c = ParameterName[index]; if (!Char.IsLetterOrDigit(c)) { throw new DataException("After initial '@', ParameterName can only have letters and digits: " + ParameterName); } } // validate DbType enum var expectedType = RowData.DeriveSystemType(DbType); // perform basic sanity check for most collection and value types if (Value != null && Value != DBNull.Value) { var vtype = Value.GetType(); if (DbType == DbType.Binary || DbType == DbType.Object || vtype.IsValueType) { } else if (vtype.IsArray) { if (((Array)Value).Rank != 1) { throw new DataException("Parameter value cannot be a multidimensional array"); } vtype = vtype.GetElementType(); IsValidatedCollection = true; } else if (vtype != typeof(string)) { // check if Value is of supported collection type var interfaces = vtype.GetInterfaces(); foreach (var intf in interfaces) { if (intf.IsGenericType) { var basetype = intf.GetGenericTypeDefinition(); if (basetype == typeof(ICollection <>) || basetype == typeof(IReadOnlyCollection <>)) { vtype = intf.GetGenericArguments()[0]; if (vtype == expectedType) { IsValidatedCollection = true; break; } } } } // do not support basic ICollection in order to avoid unboxing when writing values to request stream // boxing-unboxing can seriously affect client performance on large value sets if (!IsValidatedCollection && Value is ICollection) { throw new DataException( "To provide a collection of values as a parameter's value, use strongly typed 1-dimensional arrays" + " or generic collections implementing ICollection<T>, IReadOnlyCollection<T>."); } } if (vtype != expectedType) { throw new DataException( string.Format( "Value contains an instance of type {0}, which is different from what is implied by DbType ({1}): {2}", vtype.FullName, DbType, expectedType.FullName)); } } }