/// <summary>
        /// Returns a page of errors from the database in descending order
        /// of logged time.
        /// </summary>

        public override int GetErrors(int pageIndex, int pageSize, ICollection <ErrorLogEntry> errorEntryList)
        {
            if (pageIndex < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(pageIndex), pageIndex, null);
            }

            if (pageSize < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(pageSize), pageSize, null);
            }

            using (var connection = new SqlConnection(ConnectionString))
                using (var command = CommandExtension.GetErrorsXml(ApplicationName, pageIndex, pageSize))
                {
                    command.Connection = connection;
                    connection.Open();

                    XmlReader reader = command.ExecuteXmlReader();
                    try
                    {
                        ErrorsXmlToList(reader, errorEntryList);
                    }
                    finally
                    {
                        reader.Close();
                    }

                    CommandExtension.GetErrorsXmlOutputs(command, out var total);
                    return(total);
                }
        }
        /// <summary>
        /// Returns the specified error from the database, or null
        /// if it does not exist.
        /// </summary>

        public override ErrorLogEntry GetError(string id)
        {
            if (id == null)
            {
                throw new ArgumentNullException(nameof(id));
            }

            if (id.Length == 0)
            {
                throw new ArgumentException(null, nameof(id));
            }

            Guid errorGuid;

            try
            {
                errorGuid = new Guid(id);
            }
            catch (FormatException e)
            {
                throw new ArgumentException(e.Message, nameof(id), e);
            }

            string errorXml;

            using (SqlConnection connection = new SqlConnection(ConnectionString))
                using (SqlCommand command = CommandExtension.GetErrorXml(ApplicationName, errorGuid))
                {
                    command.Connection = connection;
                    connection.Open();
                    errorXml = (string)command.ExecuteScalar();
                }

            if (errorXml == null)
            {
                return(null);
            }

            Error error = ErrorXml.DecodeString(errorXml);

            return(new ErrorLogEntry(this, id, error));
        }
        /// <summary>
        /// Logs an error to the database.
        /// </summary>
        /// <remarks>
        /// Use the stored procedure called by this implementation to set a
        /// policy on how long errors are kept in the log. The default
        /// implementation stores all errors for an indefinite time.
        /// </remarks>

        public override string Log(Error error)
        {
            if (error == null)
            {
                throw new ArgumentNullException(nameof(error));
            }

            var errorXml = ErrorXml.EncodeString(error);
            var id       = Guid.NewGuid();

            using (SqlConnection connection = new SqlConnection(ConnectionString))
                using (SqlCommand command = CommandExtension.LogError(
                           id, ApplicationName,
                           error.HostName, error.Type, error.Source, error.Message, error.User,
                           error.StatusCode, error.Time.ToUniversalTime(), errorXml))
                {
                    command.Connection = connection;
                    connection.Open();
                    command.ExecuteNonQuery();
                    return(id.ToString());
                }
        }