/// <summary>
            /// Initializes a new instance of the <see cref="ProgramDefinitionData" /> class.
            /// </summary>
            /// <param name="type">The type.</param>
            /// <param name="schemaID">The schema identifier.</param>
            /// <param name="name">The name.</param>
            /// <param name="ordinal">The ordinal.</param>
            /// <param name="parameterName">Name of the parameter.</param>
            /// <param name="parameterType">Type of the parameter.</param>
            /// <param name="parameterSize">Size of the parameter.</param>
            /// <param name="parameterDirection">The parameter direction.</param>
            /// <param name="isReadonly">if set to <see langword="true" /> [is readonly].</param>
            public ProgramDefinitionData(
                SqlObjectType type,
                int schemaID,
                [NotNull] string name,
                int ordinal,
                [NotNull] string parameterName,
                [NotNull] SqlType parameterType,
                SqlTypeSize parameterSize,
                ParameterDirection parameterDirection,
                bool isReadonly)
            {
                if (name == null)
                {
                    throw new ArgumentNullException("name");
                }
                if (parameterName == null)
                {
                    throw new ArgumentNullException("parameterName");
                }
                if (parameterType == null)
                {
                    throw new ArgumentNullException("parameterType");
                }

                Type      = type;
                SchemaID  = schemaID;
                Name      = name;
                Parameter = new SqlProgramParameter(
                    ordinal,
                    parameterName,
                    parameterType,
                    parameterSize,
                    parameterDirection,
                    isReadonly);
            }
        public bool TryGetParameter([NotNull] string parameterName, out SqlProgramParameter parameter)
        {
            if (parameterName == null)
            {
                throw new ArgumentNullException("parameterName");
            }

            return(_parametersByName.TryGetValue(parameterName, out parameter));
        }
        public IEnumerable <SqlProgramParameter> ValidateParameters(
            [CanBeNull] IEnumerable <KeyValuePair <string, SqlDbType> > parameters,
            bool validateOrder = false)
        {
            if (parameters == null)
            {
                return(Enumerable.Empty <SqlProgramParameter>());
            }

            parameters = parameters.Enumerate();

            int sCount = parameters.Count();

            if (sCount < 1)
            {
                return(Enumerable.Empty <SqlProgramParameter>());
            }
            // ReSharper restore ConditionIsAlwaysTrueOrFalse

            int dCount = Parameters.Count();

            if (dCount < sCount)
            {
                throw new LoggingException(
                          LoggingLevel.Critical,
                          () => Resources.SqlProgramDefinition_ValidateParameters_ParameterCountsNotEqual,
                          FullName,
                          dCount,
                          sCount);
            }

            // Create list of parameters for output
            List <SqlProgramParameter> sqlParameters = new List <SqlProgramParameter>(sCount);

            if (validateOrder)
            {
                using (IEnumerator <SqlProgramParameter> p1 = Parameters.GetEnumerator())
                    using (IEnumerator <KeyValuePair <string, SqlDbType> > p2 = parameters.GetEnumerator())
                        do
                        {
                            if (!p1.MoveNext())
                            {
                                // If we still have parameters to check, we don't match - should be caught above - but sanity check.
                                if (p2.MoveNext())
                                {
                                    throw new LoggingException(
                                              LoggingLevel.Critical,
                                              () => Resources.SqlProgramDefinition_ValidateParameters_ParameterCountsNotEqual,
                                              FullName,
                                              dCount,
                                              sCount);
                                }

                                // We're done.
                                return(sqlParameters);
                            }

                            // If no more supplied parameters, matching is done.
                            if (!p2.MoveNext())
                            {
                                return(sqlParameters);
                            }

                            SqlProgramParameter parameter = p1.Current;
                            Debug.Assert(parameter != null);

                            // Add parameter to return enumeration
                            sqlParameters.Add(parameter);

                            string name = p2.Current.Key;
                            // Only check name if not null.
                            if ((name != null) &&
                                (parameter.FullName != (name = name.ToLower())))
                            {
                                throw new LoggingException(
                                          LoggingLevel.Critical,
                                          () => Resources.SqlProgramDefinition_ValidateParameters_ParameterDoesNotExist,
                                          name,
                                          FullName);
                            }

                            SqlDbType type = p2.Current.Value;
                            // Check to see if parameter accepts type
                            if (parameter.Type.SqlDbType != type)
                            {
                                throw new LoggingException(
                                          LoggingLevel.Critical,
                                          () => Resources.SqlProgramDefinition_ValidateParameters_TypeDoesNotAcceptSqlDbType,
                                          parameter.FullName,
                                          FullName,
                                          parameter.Type.FullName,
                                          type);
                            }
                        } while (true);
            }

            // We are not validating order
            foreach (KeyValuePair <string, SqlDbType> kvp in parameters)
            {
                // If we have a null parameter name, cannot possibly match.
                if (kvp.Key == null)
                {
                    throw new LoggingException(
                              LoggingLevel.Critical,
                              () => Resources.SqlProgramDefinition_ValidateParameters_MustSpecifyParameterName,
                              FullName);
                }

                SqlProgramParameter parameter;
                string name = kvp.Key.ToLower();
                if (!_parametersByName.TryGetValue(name, out parameter))
                {
                    throw new LoggingException(
                              LoggingLevel.Critical,
                              () => Resources.SqlProgramDefinition_ValidateParameters_ParameterDoesNotExist,
                              name,
                              FullName);
                }
                Debug.Assert(parameter != null);

                // Add parameter to return enumeration
                sqlParameters.Add(parameter);

                SqlDbType type = kvp.Value;
                // Check to see if parameter accepts type
                if (parameter.Type.SqlDbType != type)
                {
                    throw new LoggingException(
                              LoggingLevel.Critical,
                              () => Resources.SqlProgramDefinition_ValidateParameters_TypeDoesNotAcceptSqlDbType,
                              parameter.FullName,
                              FullName,
                              parameter.Type.FullName,
                              type);
                }
            }
            return(sqlParameters);
        }