System.Data.SqlClient.SqlParameter.GetActualFieldsAndProperties C# (CSharp) Méthode

GetActualFieldsAndProperties() private méthode

private GetActualFieldsAndProperties ( List &fields, SmiMetaDataPropertyCollection &props, System.Data.SqlClient.ParameterPeekAheadValue &peekAhead ) : void
fields List
props SmiMetaDataPropertyCollection
peekAhead System.Data.SqlClient.ParameterPeekAheadValue
Résultat void
        private void GetActualFieldsAndProperties(out List<MSS.SmiExtendedMetaData> fields, out SmiMetaDataPropertyCollection props, out ParameterPeekAheadValue peekAhead)
        {
            fields = null;
            props = null;
            peekAhead = null;

            object value = GetCoercedValue();
            if (value is SqlDataReader)
            {
                fields = new List<MSS.SmiExtendedMetaData>(((SqlDataReader)value).GetInternalSmiMetaData());
                if (fields.Count <= 0)
                {
                    throw SQL.NotEnoughColumnsInStructuredType();
                }

                bool[] keyCols = new bool[fields.Count];
                bool hasKey = false;
                for (int i = 0; i < fields.Count; i++)
                {
                    MSS.SmiQueryMetaData qmd = fields[i] as MSS.SmiQueryMetaData;
                    if (null != qmd && !qmd.IsKey.IsNull && qmd.IsKey.Value)
                    {
                        keyCols[i] = true;
                        hasKey = true;
                    }
                }

                // Add unique key property, if any found.
                if (hasKey)
                {
                    props = new SmiMetaDataPropertyCollection();
                    props[MSS.SmiPropertySelector.UniqueKey] = new MSS.SmiUniqueKeyProperty(new List<bool>(keyCols));
                }
            }
            else if (value is IEnumerable<SqlDataRecord>)
            {
                // must grab the first record of the enumerator to get the metadata
                IEnumerator<MSS.SqlDataRecord> enumerator = ((IEnumerable<MSS.SqlDataRecord>)value).GetEnumerator();
                MSS.SqlDataRecord firstRecord = null;
                try
                {
                    // no need for fields if there's no rows or no columns -- we'll be sending a null instance anyway.
                    if (enumerator.MoveNext())
                    {
                        firstRecord = enumerator.Current;
                        int fieldCount = firstRecord.FieldCount;
                        if (0 < fieldCount)
                        {
                            // It's valid!  Grab those fields.
                            bool[] keyCols = new bool[fieldCount];
                            bool[] defaultFields = new bool[fieldCount];
                            bool[] sortOrdinalSpecified = new bool[fieldCount];
                            int maxSortOrdinal = -1;  // largest sort ordinal seen, used to optimize locating holes in the list
                            bool hasKey = false;
                            bool hasDefault = false;
                            int sortCount = 0;
                            SmiOrderProperty.SmiColumnOrder[] sort = new SmiOrderProperty.SmiColumnOrder[fieldCount];
                            fields = new List<MSS.SmiExtendedMetaData>(fieldCount);
                            for (int i = 0; i < fieldCount; i++)
                            {
                                SqlMetaData colMeta = firstRecord.GetSqlMetaData(i);
                                fields.Add(MSS.MetaDataUtilsSmi.SqlMetaDataToSmiExtendedMetaData(colMeta));
                                if (colMeta.IsUniqueKey)
                                {
                                    keyCols[i] = true;
                                    hasKey = true;
                                }

                                if (colMeta.UseServerDefault)
                                {
                                    defaultFields[i] = true;
                                    hasDefault = true;
                                }

                                sort[i].Order = colMeta.SortOrder;
                                if (SortOrder.Unspecified != colMeta.SortOrder)
                                {
                                    // SqlMetaData takes care of checking for negative sort ordinals with specified sort order

                                    // bail early if there's no way sort order could be monotonically increasing
                                    if (fieldCount <= colMeta.SortOrdinal)
                                    {
                                        throw SQL.SortOrdinalGreaterThanFieldCount(i, colMeta.SortOrdinal);
                                    }

                                    // Check to make sure we haven't seen this ordinal before
                                    if (sortOrdinalSpecified[colMeta.SortOrdinal])
                                    {
                                        throw SQL.DuplicateSortOrdinal(colMeta.SortOrdinal);
                                    }

                                    sort[i].SortOrdinal = colMeta.SortOrdinal;
                                    sortOrdinalSpecified[colMeta.SortOrdinal] = true;
                                    if (colMeta.SortOrdinal > maxSortOrdinal)
                                    {
                                        maxSortOrdinal = colMeta.SortOrdinal;
                                    }
                                    sortCount++;
                                }
                            }

                            if (hasKey)
                            {
                                props = new SmiMetaDataPropertyCollection();
                                props[MSS.SmiPropertySelector.UniqueKey] = new MSS.SmiUniqueKeyProperty(new List<bool>(keyCols));
                            }

                            if (hasDefault)
                            {
                                // May have already created props list in unique key handling
                                if (null == props)
                                {
                                    props = new SmiMetaDataPropertyCollection();
                                }

                                props[MSS.SmiPropertySelector.DefaultFields] = new MSS.SmiDefaultFieldsProperty(new List<bool>(defaultFields));
                            }

                            if (0 < sortCount)
                            {
                                // validate monotonically increasing sort order.
                                //  Since we already checked for duplicates, we just need
                                //  to watch for values outside of the sortCount range.
                                if (maxSortOrdinal >= sortCount)
                                {
                                    // there is at least one hole, find the first one
                                    int i;
                                    for (i = 0; i < sortCount; i++)
                                    {
                                        if (!sortOrdinalSpecified[i])
                                        {
                                            break;
                                        }
                                    }
                                    Debug.Assert(i < sortCount, "SqlParameter.GetActualFieldsAndProperties: SortOrdinal hole-finding algorithm failed!");
                                    throw SQL.MissingSortOrdinal(i);
                                }

                                // May have already created props list
                                if (null == props)
                                {
                                    props = new SmiMetaDataPropertyCollection();
                                }

                                props[MSS.SmiPropertySelector.SortOrder] = new MSS.SmiOrderProperty(
                                        new List<SmiOrderProperty.SmiColumnOrder>(sort));
                            }

                            // pack it up so we don't have to rewind to send the first value
                            peekAhead = new ParameterPeekAheadValue();
                            peekAhead.Enumerator = enumerator;
                            peekAhead.FirstRecord = firstRecord;

                            // now that it's all packaged, make sure we don't dispose it.
                            enumerator = null;
                        }
                        else
                        {
                            throw SQL.NotEnoughColumnsInStructuredType();
                        }
                    }
                    else
                    {
                        throw SQL.IEnumerableOfSqlDataRecordHasNoRows();
                    }
                }
                finally
                {
                    if (enumerator != null)
                    {
                        enumerator.Dispose();
                    }
                }
            }
            else if (value is DbDataReader)
            {
                // For ProjectK\CoreCLR, DbDataReader no longer supports GetSchema
                // So instead we will attempt to generate the metadata from the Field Type alone
                var reader = (DbDataReader)value;
                if (reader.FieldCount <= 0)
                {
                    throw SQL.NotEnoughColumnsInStructuredType();
                }

                fields = new List<MSS.SmiExtendedMetaData>(reader.FieldCount);
                for (int i = 0; i < reader.FieldCount; i++)
                {
                    fields.Add(MSS.MetaDataUtilsSmi.SmiMetaDataFromType(reader.GetName(i), reader.GetFieldType(i)));
                }
            }
        }