CPQuery SQL字符串拼接之 —— 湊熱鬧


昨天拜讀了一下 Fish Li 的 CPQuery, 解決拼接SQL的新方法,整體上還是很贊的,提供了一種新的數據庫查詢方式,這讓我想起了很久之前 CoolCode 寫的一個字符串拼接類(StringJoiner),個人認為很不錯,確實拯救了不少前同事留下來的爛代碼。

 

不過,我認為 Fish Li 的代碼還有一些不足之處,因為涉及的改動比較多,所以我在這里另辟一塊地方,發表出來,希望 Fish Li 理解我的意思,謝謝!代碼整體上借用 Fish Li 的思想,不過在一些細節問題上的處理有些不同,不多說了。上代碼:

using System;
using System.Data;
using System.Data.SqlClient;
using System.Text;

namespace TestParameterJoin
{
    class Program
    {
        static void Main(string[] args)
        {
            var con = new SqlConnection();
            var cmd = con.CreateCommand();
            cmd.CommandText = "select * from table where 1 = 1";

            var builder = cmd.AsBuilder() + " and a = " + "abc" +
                                            " and b = " + 3 +
                                            " and c = " + true +
                                            " and d = " + DateTime.Now;

            // Build: select * from table where 1 = 1 and a = @p0 and b = @p1 and c = @p2 and d = @p3
            builder.Build();

            // 接着做你的數據庫操作
        }
    }

    public sealed class DbCommandBuilder
    {
        private StringBuilder sbSql = new StringBuilder();
        private IDbCommand cmd = null;
        private bool isBuilded = false;

        public DbCommandBuilder(IDbCommand command)
        {
            cmd = command;
        }

        public static DbCommandBuilder operator +(DbCommandBuilder builder, string obj)
        {
            if (builder.isBuilded) throw new ApplicationException("Has builded!");

            var isParameter = obj.IndexOf('=') == -1;
            var parameterName = GetParameterName(builder);

            if (isParameter)
                builder.AppendParameter(DbType.String, () => (object)obj ?? DBNull.Value);
            else
                builder.sbSql.Append(obj).Append(parameterName);

            return builder;
        }

        public static DbCommandBuilder operator +(DbCommandBuilder builder, int? obj)
        {
            if (builder.isBuilded) throw new ApplicationException("Has builded!");

            return builder.AppendParameter(DbType.Int32, () => obj.HasValue ? (object)obj.Value : DBNull.Value);
        }

        public static DbCommandBuilder operator +(DbCommandBuilder builder, bool? obj)
        {
            if (builder.isBuilded) throw new ApplicationException("Has builded!");

            return builder.AppendParameter(DbType.Boolean, () => obj.HasValue ? (object)(obj.Value ? 1 : 0) : DBNull.Value);
        }

        public static DbCommandBuilder operator +(DbCommandBuilder builder, DateTime? obj)
        {
            if (builder.isBuilded) throw new ApplicationException("Has builded!");

            return builder.AppendParameter(DbType.DateTime, () => obj.HasValue ? (object)obj.Value : DBNull.Value);
        }

        // 這里你還可以繼續添加你想要的類型

        private DbCommandBuilder AppendParameter(DbType dbType, Func<object> func)
        {
            var parameterName = GetParameterName(this);

            var param = cmd.CreateParameter();
            param.DbType = dbType;
            param.Value = func();
            param.ParameterName = parameterName;

            cmd.Parameters.Add(param);

            return this;
        }

        private static string GetParameterName(DbCommandBuilder builder)
        {
            return string.Format("@p{0}", builder.cmd.Parameters.Count);
        }

        public IDbCommand Build()
        {
            isBuilded = true;
            var sql = sbSql.ToString();
            if (!string.IsNullOrWhiteSpace(sql))
                cmd.CommandText += sql;
            return cmd;
        }

        public override string ToString()
        {
            return cmd.CommandText + (isBuilded ? string.Empty : sbSql.ToString());
        }
    }

    public static class DbCommandBuilderExtension
    {
        public static DbCommandBuilder AsBuilder(this IDbCommand cmd)
        {
            return new DbCommandBuilder(cmd);
        }
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM