/// <summary>
        /// Converts the value of a specified object to an equivalent string representation using specified format and culture-specific formatting information.
        /// </summary>
        /// <param name="format">A format string containing formatting specifications.</param>
        /// <param name="arg">An object to format.</param>
        /// <param name="formatProvider">An object that supplies format information about the current instance.</param>
        /// <returns>
        /// The string representation of the value of <paramref name="arg" />, formatted as specified by <paramref name="format" /> and <paramref name="formatProvider" />.
        /// </returns>
        public string Format(string format, object arg, IFormatProvider formatProvider)
        {
            // Check whether this is an appropriate callback
            if (!this.Equals(formatProvider))
            {
                return(null);
            }
            if (arg == null)
            {
                return(null);
            }

            var    parts = (format ?? "").Split(':');
            var    sql   = new SqlFormatter();
            string formatString;

            switch (parts[0])
            {
            case "aml":
                formatString = string.Join(":", parts, 1, parts.Length - 1);
                return(Format(arg,
                              n => n.ToString(format, CultureInfo.InvariantCulture),
                              o => GetString(o, formatString)));

            case "sql":
                formatString = string.Join(":", parts, 1, parts.Length - 1);
                return(XmlEscape(sql.Format(formatString, arg, sql)));

            case "rawsql":
                formatString = string.Join(":", parts, 1, parts.Length - 1);
                return(sql.Format(formatString, arg, sql));

            default:
                formatString = format;
                return(Format(arg,
                              n => n.ToString(format, CultureInfo.InvariantCulture),
                              o => XmlEscape(GetString(o, formatString))));
            }
        }
    public string Format(string format, object arg, IFormatProvider formatProvider)
    {
      // Check whether this is an appropriate callback              
      if (!this.Equals(formatProvider)) return null;
      if (arg == null) return null;

      var parts = (format ?? "").Split(':');
      var sql = new SqlFormatter(this);
      string formatString;

      switch (parts[0])
      {
        case "aml":
          formatString = string.Join(":", parts, 1, parts.Length - 1);
          return Format(arg,
            n => n.ToString(format, CultureInfo.InvariantCulture),
            o => GetString(o, formatString));
        case "sql":
          formatString = string.Join(":", parts, 1, parts.Length - 1);
          return XmlEscape(sql.Format(formatString, arg, sql));
        case "rawsql":
          formatString = string.Join(":", parts, 1, parts.Length - 1);
          return sql.Format(formatString, arg, sql);
        default:
          formatString = format;
          return Format(arg,
            n => n.ToString(format, CultureInfo.InvariantCulture),
            o => XmlEscape(GetString(o, formatString)));
      }
    }
 private string SqlReplace(string query)
 {
   var builder = new StringBuilder(query.Length);
   var formatter = new SqlFormatter(_context);
   SqlReplace(query, '@', builder, p =>
   {
     object value;
     if (TryGetParamValue(p, out value))
     {
       IFormattable num;
       if (ServerContext.TryCastNumber(value, out num))
       {
         return formatter.Format(num);
       }
       else if (builder.ToString().EndsWith(" in ") && value is IEnumerable)
       {
         return "(" + RenderSqlEnum(value, true, o => formatter.Format(o)) + ")";
       }
       else
       {
         return "N'" + RenderSqlEnum(value, false, o => formatter.Format(o)) + "'";
       }
     }
     else
     {
       return "@" + p;
     }
   });
   return builder.ToString();
 }