예제 #1
0
 public override Type GetFieldType(int i)
 {
     return(RowData.DeriveSystemType(m_scheme.RequireField(i).DataType));
 }
예제 #2
0
        /// <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));
                }
            }
        }