修改PDF.NET SOD源代码以支持加密的数据库连接字符串

看了下PDF.NET SOD的代码,好像数据库连接字符串,只支持明文写在config文件的。这在一定程度上存在数据库账号密码泄漏的风险,于是鼓捣了源代码中的PWMIS.DataProvider.Adapter.MyDB类,让PDF.NET SOD能读取加密过的字符串。

首先上加密解密类代码:

using System;
using System.Security.Cryptography;
using System.Text;

namespace Cxw.Common
{
    /// <summary>
    /// DES对称加密/解密类
    /// </summary>
    public class DES
    {
        #region ========加密========

        /// <summary>
        /// 加密数据
        /// </summary>
        /// <param name="Text"></param>
        /// <param name="sKey"></param>
        /// <returns></returns>
        public static string Encrypt(string Text, string sKey = "^#%^#$#^%*)#*JJDKS$")
        {
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            byte[] inputByteArray;
            inputByteArray = Encoding.Default.GetBytes(Text);
            des.Key = ASCIIEncoding.ASCII.GetBytes(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
            des.IV = ASCIIEncoding.ASCII.GetBytes(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
            cs.Write(inputByteArray, 0, inputByteArray.Length);
            cs.FlushFinalBlock();
            StringBuilder ret = new StringBuilder();
            foreach (byte b in ms.ToArray())
            {
                ret.AppendFormat("{0:X2}", b);
            }
            return ret.ToString();
        }
        #endregion

        #region ========解密========
        /// <summary>
        /// 解密数据
        /// </summary>
        /// <param name="Text"></param>
        /// <param name="sKey"></param>
        /// <returns></returns>
        public static string Decrypt(string Text, string sKey = "^#%^#$#^%*)#*JJDKS$")
        {
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            int len;
            len = Text.Length / 2;
            byte[] inputByteArray = new byte[len];
            int x, i;
            for (x = 0; x < len; x++)
            {
                i = Convert.ToInt32(Text.Substring(x * 2, 2), 16);
                inputByteArray[x] = (byte)i;
            }
            des.Key = ASCIIEncoding.ASCII.GetBytes(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
            des.IV = ASCIIEncoding.ASCII.GetBytes(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
            cs.Write(inputByteArray, 0, inputByteArray.Length);
            cs.FlushFinalBlock();
            return Encoding.Default.GetString(ms.ToArray());
        }

        #endregion

    }
}

PWMIS.DataProvider.Adapter.MyDB类,主要是加了静态字段isEncrypt,这个字段值是从config文件读取appSettings节点的添加项IsEncrypt的值,相当于开关:

        /// <summary>
        /// 是否加密数据库连接字符串
        /// </summary>
        private static bool isEncrypt = ConfigurationManager.AppSettings["IsEncrypt"] == "true";

然后在读取连接字符中的时候根据这个开关的设置判断是否需要解密。

简单测试了下(没有测试完所有的方法),暂时没有发现问题。

还是要上修改过的完整PWMIS.DataProvider.Adapter.MyDB类代码:

/*
 * ========================================================================
 * Copyright(c) 2006-2010 PWMIS, All Rights Reserved.
 * Welcom use the PDF.NET (PWMIS Data Process Framework).
 * See more information,Please goto http://www.pwmis.com/sqlmap 
 * ========================================================================
 * MyDB.cs
 * 该类的作用:提供便利的方式访问数据库实例和操作数据集
 * 
 * 作者:邓太华     时间:2008-10-12
 * 版本:V3.0
 * 
 * 修改者:         时间:2011.11.16                
 * 修改说明:增加自动保存数据集的功能
 * ========================================================================
*/
using System;
using System.Data;
using System.Configuration;
using PWMIS.DataProvider.Data;
using PWMIS.Common;

namespace PWMIS.DataProvider.Adapter
{
    /// <summary>
    /// 应用程序数据访问实例,提供单例模式和工厂模式创建实例对象,根据应用程序配置文件自动创建特定的数据访问对象。
    /// 2008.5.23 增加动态数据集更新功能,7.24增加线程安全的静态实例。
    /// 2009.4.1  增加SQLite 数据库支持。
    /// 2010.1.6  增加 connectionStrings 配置支持
    /// </summary>
    public class MyDB
    {
        private static AdoHelper _instance = null;
        private string _msg = string.Empty;
        private static object lockObj = new object();
        /// <summary>
        /// 是否加密数据库连接字符串
        /// </summary>
        private static bool isEncrypt = ConfigurationManager.AppSettings["IsEncrypt"] == "true";

        #region 获取静态实例

        /// <summary>
        /// 数据访问静态实例对象,读取加密的连接字符串,已经禁止当前对象执行事务。如果有事务并且有可能存在并发访问,请创建该AdoHelper类的动态实例对象。
        /// </summary>
        public static AdoHelper Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (lockObj)
                    {
                        if (_instance == null)
                        {
                            _instance = MyDB.GetDBHelper();
                            _instance.AllowTransaction = false;
                        }
                    }
                }
                return _instance;
            }
        }

        #endregion

        #region 获取动态实例对象
        /// <summary>
        /// 通过配置文件获得数据访问对象实例,
        /// 请在应用程序配置文件中创建 EngineType 键,值为[DB],同时需要创建 [DB]HelperAssembly,[DB]HelperType ,[DB]ConnectionString 键,[DB]值为SQLSERVER/OLEDB/ODBC/ORACLE 之一
        /// 如果未指定 EngineType 键,则使用 connectionStrings 配置节的第一个连接配置信息,必须指明 providerName,可以使用下面的形式:
        /// providerName="PWMIS.DataProvider.Data.SqlServer,PWMIS.Core"
        /// 也可以直接使用 下面的形式:
        /// providerName="SqlServer" ,当然,这种形式的提供程序程序集默认就是 PWMIS.CommonDataProvider.Data 。
        /// 如果有多个,默认取最后一个 providerName
        /// </summary>
        /// <returns>数据访问对象实例</returns>
        public static AdoHelper GetDBHelper()
        {
            string engineType = ConfigurationSettings.AppSettings["EngineType"];
            AdoHelper helper = null;
            if (string.IsNullOrEmpty(engineType))
            {
                //从 connectionStrings 读取
                if (ConfigurationManager.ConnectionStrings.Count == 0)
                    throw new Exception("appSettings 未指明 EngineType 配置键,也未在 connectionStrings 配置节配置连接信息");

                helper = GetDBHelperByConnectionSetting(ConfigurationManager.ConnectionStrings[ConfigurationManager.ConnectionStrings.Count - 1]);
            }
            else
            {
                helper = GetDBHelper(engineType);
                helper.ConnectionString = GetConnectionString();
            }
            return helper;
        }

        /// <summary>
        /// 从 connectionStrings 配置节获取指定 数据连接名称的数据访问对象实例
        /// </summary>
        /// <param name="name">数据连接名称</param>
        /// <returns></returns>
        public static AdoHelper GetDBHelperByConnectionName(string name)
        {
            ConnectionStringSettings connSetting = ConfigurationManager.ConnectionStrings[name];
            if (connSetting == null)
                throw new Exception("未在 connectionStrings 配置节找到指定的 连接名称:" + name);

            return GetDBHelperByConnectionSetting(connSetting);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="connSetting"></param>
        /// <returns></returns>
        private static AdoHelper GetDBHelperByConnectionSetting(ConnectionStringSettings connSetting)
        {
            return GetDBHelperByProviderString(connSetting.ProviderName, connSetting.ConnectionString);
        }

        /// <summary>
        /// 根据提供程序名称字符串和连接字符串,创建提供程序实例
        /// </summary>
        /// <param name="providerName">供程序名称字符串,格式为:提供程序全名称,程序集名称</param>
        /// <param name="connectionString">连接字符串</param>
        /// <returns></returns>
        public static AdoHelper GetDBHelperByProviderString(string providerName, string connectionString)
        {
            string[] providerInfo = providerName.Split(',');
            string helperAssembly;
            string helperType;

            if (isEncrypt)
            {
                providerName = Cxw.Common.DES.Decrypt(providerName);
                connectionString = Cxw.Common.DES.Decrypt(connectionString);
            }

            providerInfo = providerName.Split(',');

            if (providerInfo.Length == 1)
            {
                helperAssembly = "PWMIS.Core";
                helperType = "PWMIS.DataProvider.Data." + providerName;
            }
            else
            {
                helperAssembly = providerInfo[1].Trim();
                helperType = providerInfo[0].Trim();
            }
            return GetDBHelper(helperAssembly, helperType, connectionString);
        }

        /// <summary>
        /// 通过指定的数据库类型(值为SQLSERVER/OLEDB/ODBC/ORACLE 之一)和连接字符串创建一个新的数据访问对象,
        /// 需要配置[DB]HelperAssembly,[DB]HelperType 键,[DB]值为SQLSERVER/OLEDB/ODBC/ORACLE 之一
        /// </summary>
        /// <param name="EngineType">数据库类型(值为SQLSERVER/OLEDB/ODBC/ORACLE 之一)</param>
        /// <param name="ConnectionString">连接字符串</param>
        /// <returns>数据访问对象</returns>
        public static AdoHelper GetDBHelper(string EngineType, string ConnectionString)
        {
            AdoHelper helper = GetDBHelper(EngineType);
            helper.ConnectionString = isEncrypt ? Cxw.Common.DES.Decrypt(ConnectionString) : ConnectionString;
            return helper;
        }

        /// <summary>
        /// 根据数据库管理系统枚举类型和连接字符串创建一个新的数据访问对象实例
        /// </summary>
        /// <param name="DbmsType">数据库类型媒介,有ACCESS/MYSQL/ORACLE/SQLSERVER/SYSBASE/UNKNOWN </param>
        /// <param name="ConnectionString">连接字符串</param>
        /// <returns>数据访问对象</returns>
        public static AdoHelper GetDBHelper(DBMSType DbmsType, string ConnectionString)
        {
            string EngineType = "";
            switch (DbmsType)
            {
                case DBMSType.Access:
                    EngineType = "OleDb"; break;
                case DBMSType.MySql:
                    EngineType = "Odbc"; break;
                case DBMSType.Oracle:
                    EngineType = "Oracle"; break;
                case DBMSType.SqlServer:
                    EngineType = "SqlServer"; break;
                case DBMSType.SqlServerCe:
                    EngineType = "SqlServerCe"; break;
                case DBMSType.Sysbase:
                    EngineType = "OleDb"; break;
                case DBMSType.SQLite:
                    EngineType = "SQLite"; break;
                case DBMSType.UNKNOWN:
                    EngineType = "Odbc"; break;
            }
            AdoHelper helper = GetDBHelper(EngineType);
            helper.ConnectionString = isEncrypt ? Cxw.Common.DES.Decrypt(ConnectionString) : ConnectionString;
            return helper;
        }

        /// <summary>
        /// 根据程序集名称和数据访问对象类型创建一个新的数据访问对象实例。
        /// </summary>
        /// <param name="HelperAssembly">程序集名称</param>
        /// <param name="HelperType">数据访问对象类型</param>
        /// <param name="ConnectionString">连接字符串</param>
        /// <returns>数据访问对象</returns>
        public static AdoHelper GetDBHelper(string HelperAssembly, string HelperType, string ConnectionString)
        {
            AdoHelper helper = null;// CommonDB.CreateInstance(HelperAssembly, HelperType);
            if (HelperAssembly == "PWMIS.Core")
            {
                switch (HelperType)
                {
                    case "PWMIS.DataProvider.Data.SqlServer": helper = new SqlServer(); break;
                    case "PWMIS.DataProvider.Data.Oracle": helper = new Oracle(); break;
                    case "PWMIS.DataProvider.Data.OleDb": helper = new OleDb(); break;
                    case "PWMIS.DataProvider.Data.Odbc": helper = new Odbc(); break;
                    case "PWMIS.DataProvider.Data.Access": helper = new Access(); break;
                    //case "PWMIS.DataProvider.Data.SqlServerCe": helper = new SqlServerCe(); break;
                    default: helper = new SqlServer(); break;
                }
            }
            else
            {
                helper = CommonDB.CreateInstance(HelperAssembly, HelperType);
            }
            helper.ConnectionString = isEncrypt ? Cxw.Common.DES.Decrypt(ConnectionString) : ConnectionString;
            return helper;
        }

        /// <summary>
        /// 获得数据访问对象实例,EngineType值为SQLSERVER/OLEDB/ODBC/ORACLE 之一,默认使用 PWMIS.CommonDataProvider.Data.SqlServer
        /// </summary>
        /// <param name="EngineType">数据库引擎类型</param>
        /// <returns>数据访问对象实例</returns>
        private static AdoHelper GetDBHelper(string EngineType)
        {
            string assembly = null;
            string type = null;
            bool isAppSettingsIsNull = false;

            if (isEncrypt)
            {
                EngineType = Cxw.Common.DES.Decrypt(EngineType);
            }

            switch (EngineType.ToUpper())
            {
                case "SQLSERVER":
                    assembly = ConfigurationManager.AppSettings["SqlServerHelperAssembly"];
                    type = ConfigurationManager.AppSettings["SqlServerHelperType"];
                    if (string.IsNullOrEmpty(assembly))
                    {
                        assembly = "PWMIS.Core";
                        type = "PWMIS.DataProvider.Data.SqlServer";
                        isAppSettingsIsNull = true;
                    }
                    break;
                case "SQLSERVERCE":
                    assembly = ConfigurationManager.AppSettings["SqlServerCeHelperAssembly"];
                    type = ConfigurationManager.AppSettings["SqlServerCeHelperType"];
                    if (string.IsNullOrEmpty(assembly))
                    {
                        assembly = "PWMIS.Core";
                        type = "PWMIS.DataProvider.Data.SqlServerCe";
                        isAppSettingsIsNull = true;
                    }
                    break;
                case "OLEDB":
                    assembly = ConfigurationManager.AppSettings["OleDbHelperAssembly"];
                    type = ConfigurationManager.AppSettings["OleDbHelperType"];
                    if (string.IsNullOrEmpty(assembly))
                    {
                        assembly = "PWMIS.Core";
                        type = "PWMIS.DataProvider.Data.OleDb";
                        isAppSettingsIsNull = true;
                    }
                    break;
                case "ACCESS":
                    assembly = ConfigurationManager.AppSettings["OleDbHelperAssembly"];
                    type = ConfigurationManager.AppSettings["OleDbHelperType"];
                    if (string.IsNullOrEmpty(assembly))
                    {
                        assembly = "PWMIS.Core";
                        type = "PWMIS.DataProvider.Data.Access";
                        isAppSettingsIsNull = true;
                    }
                    break;
                case "ODBC":
                    assembly = ConfigurationManager.AppSettings["OdbcHelperAssembly"];
                    type = ConfigurationManager.AppSettings["OdbcHelperType"];
                    if (string.IsNullOrEmpty(assembly))
                    {
                        assembly = "PWMIS.Core";
                        type = "PWMIS.DataProvider.Data.Odbc";
                        isAppSettingsIsNull = true;
                    }
                    break;
                case "ORACLE":
                    assembly = ConfigurationManager.AppSettings["OracleHelperAssembly"];
                    type = ConfigurationManager.AppSettings["OracleHelperType"];
                    if (string.IsNullOrEmpty(assembly))
                    {
                        assembly = "PWMIS.Core";
                        type = "PWMIS.DataProvider.Data.Oracle";
                        isAppSettingsIsNull = true;
                    }
                    break;
                //不再支持这里的SQLite类型,因为它在64位,32位,windows,linux 下面有不同的驱动程序,无法在这里确定
                //case "SQLITE":
                //    assembly = ConfigurationSettings.AppSettings["SQLiteHelperAssembly"];
                //    type = ConfigurationSettings.AppSettings["SQLiteHelperType"];
                //    if (string.IsNullOrEmpty(assembly))
                //    {
                //        assembly = "PWMIS.DataProvider.Data.SQLite";
                //        type = "PWMIS.DataProvider.Data.SQLite";
                //        isAppSettingsIsNull = true;
                //    }
                //    break;
                default:
                    assembly = "PWMIS.DataProvider.Data";
                    type = "PWMIS.DataProvider.Data.SqlServer";
                    isAppSettingsIsNull = true;
                    break;
            }
            if (isEncrypt && !isAppSettingsIsNull)
            {
                assembly = Cxw.Common.DES.Decrypt(assembly);
                type = Cxw.Common.DES.Decrypt(type);
            }
            return GetDBHelper(assembly, type, null);
        }

        #endregion

        #region 公共静态方法

        /// <summary>
        /// 获得数据访问连接字符串,请在应用程序配置文件中创建 EngineType,[DB]HelperAssembly,[DB]HelperType ,[DB]ConnectionString键,值为SQLSERVER/OLEDB/ODBC/ORACLE 之一
        /// 如果没有找到 [DB]ConnectionString 键,也可以直接使用 ConnectionString 键
        /// </summary>
        /// <returns>数据访问连接字符串</returns>
        public static string GetConnectionString()
        {
            string connectionString = null;

            switch (isEncrypt ? Cxw.Common.DES.Decrypt(ConfigurationSettings.AppSettings["EngineType"]) : ConfigurationSettings.AppSettings["EngineType"])
            {
                case "SQLSERVER":
                    connectionString = ConfigurationSettings.AppSettings["SqlServerConnectionString"];
                    break;
                case "OLEDB":
                    connectionString = ConfigurationSettings.AppSettings["OleDbConnectionString"];
                    break;
                case "ODBC":
                    connectionString = ConfigurationSettings.AppSettings["OdbcConnectionString"];
                    break;
                case "ORACLE":
                    connectionString = ConfigurationSettings.AppSettings["OracleConnectionString"];
                    break;
                case "SQLITE":
                    connectionString = ConfigurationSettings.AppSettings["SQLiteConnectionString"];
                    break;
            }

            if (string.IsNullOrEmpty(connectionString))
            {
                connectionString = isEncrypt ? Cxw.Common.DES.Decrypt(ConfigurationSettings.AppSettings["ConnectionString"]) : ConfigurationSettings.AppSettings["ConnectionString"];
            }
            else if (isEncrypt)
            {
                connectionString = Cxw.Common.DES.Decrypt(connectionString);
            }

            return connectionString;
        }

        /// <summary>
        /// 更新数据集(采用参数形式),数据表如果指定了主键那么执行更新操作,否则执行插入操作。
        /// </summary>
        /// <param name="ds">数据集</param>
        /// <returns>查询结果受影响的行数</returns>
        public static int UpdateDataSet(DataSet ds)
        {
            int count = 0;
            foreach (DataTable dt in ds.Tables)
            {
                if (dt.PrimaryKey.Length > 0)
                {
                    count += UpdateDataTable(dt, GetSqlUpdate(dt));
                }
                else
                {
                    count += UpdateDataTable(dt, GetSqlInsert(dt));
                }// end if
            }//end for
            return count;
        }//end function

        /// <summary>
        /// 自动将数据集中的数据更新或者插入到数据库
        /// <remarks>更新时间:2011.11.16</remarks>
        /// </summary>
        /// <param name="ds"></param>
        /// <param name="DB"></param>
        /// <returns></returns>
        public static int SaveDataSet(DataSet ds, CommonDB DB)
        {
            int count = 0;
            foreach (DataTable dt in ds.Tables)
            {
                string insertSql = GetSqlInsert(dt);
                string updateSql = GetSqlUpdate(dt);
                count += SaveDataTable(dt, insertSql, updateSql, DB);
            }//end for
            return count;
        }
        /// <summary>
        /// 根据数据集中在指定的表中,根据表中的指定列的值在数据源中删除数据
        /// </summary>
        /// <param name="ds">数据集</param>
        /// <param name="tableName">表名称</param>
        /// <param name="columnName">列名</param>
        /// <returns>查询所影响的行数</returns>
        public static int DeleteDataSet(DataSet ds, string tableName, string columnName)
        {
            DataTable dt = ds.Tables[tableName];

            CommonDB DB = MyDB.GetDBHelper();
            string ParaChar = GetDBParaChar(DB);
            int count = 0;

            string sqlDelete = "DELETE FROM " + tableName + " WHERE " + columnName + "=" + ParaChar + columnName;

            DB.BeginTransaction();
            try
            {
                foreach (DataRow dr in dt.Rows)
                {
                    IDataParameter[] paras = { DB.GetParameter(ParaChar + columnName, dr[columnName]) };
                    count += DB.ExecuteNonQuery(sqlDelete, CommandType.Text, paras);
                    if (DB.ErrorMessage != "")
                        throw new Exception(DB.ErrorMessage);
                    if (count >= dt.Rows.Count) break;
                }
                DB.Commit();
            }
            catch (Exception ex)
            {
                DB.Rollback();
                throw ex;
            }
            return count;

        }

        #endregion

        #region 公共动态实例方法
        /// <summary>
        /// 获取当前操作信息
        /// </summary>
        public string Message
        {
            get { return _msg; }
        }
        /// <summary>
        /// 更新数据集,带数据访问对象
        /// </summary>
        /// <param name="ds">数据集</param>
        /// <param name="DB">数据访问对象</param>
        /// <returns></returns>
        public int UpdateDataSet(DataSet ds, CommonDB DB)
        {
            int count = 0;
            foreach (DataTable dt in ds.Tables)
            {
                if (dt.PrimaryKey.Length > 0)
                {
                    count += UpdateDataTable(dt, GetSqlUpdate(dt), DB);
                    _msg = "已经更新记录" + count + "条";
                }
                else
                {
                    count += UpdateDataTable(dt, GetSqlInsert(dt), DB);
                    _msg = "已经插入记录" + count + "条";
                }// end if
            }//end for
            return count;
        }//end function

        /// <summary>
        /// 根据数据集中在指定的表中,根据表中的指定列的值在数据源中删除数据,带数据访问对象
        /// </summary>
        /// <param name="ds">数据集</param>
        /// <param name="tableName">表名称</param>
        /// <param name="columnName">列名</param>
        /// <param name="DB">数据访问对象</param>
        /// <returns></returns>
        public int DeleteDataSet(DataSet ds, string tableName, string columnName, CommonDB DB)
        {
            DataTable dt = ds.Tables[tableName];
            string ParaChar = GetDBParaChar(DB);
            int count = 0;
            string sqlDelete = "DELETE FROM " + tableName + " WHERE " + columnName + "=" + ParaChar + columnName;
            foreach (DataRow dr in dt.Rows)
            {
                IDataParameter[] paras = { DB.GetParameter(ParaChar + columnName, dr[columnName]) };
                count += DB.ExecuteNonQuery(sqlDelete, CommandType.Text, paras);
                if (DB.ErrorMessage != "")
                    throw new Exception(DB.ErrorMessage);
                if (count >= dt.Rows.Count) break;
            }
            return count;
        }

        /// <summary>
        /// 根据主键信息从数据源查询数据表到数据集中
        /// </summary>
        /// <param name="tableName">数据源中的表名称</param>
        /// <param name="pkNames">主键名称数组</param>
        /// <param name="pkValues">主键值数组,必须和主键名对应</param>
        /// <returns>数据集</returns>
        public DataSet SelectDataSet(string tableName, string[] pkNames, object[] pkValues)
        {
            return SelectDataSet("*", tableName, pkNames, pkValues);
        }

        /// <summary>
        /// 根据主键信息从数据源查询数据表到数据集中
        /// </summary>
        /// <param name="fields">字段列表</param>
        /// <param name="tableName">数据源中的表名称</param>
        /// <param name="pkNames">主键名称数组</param>
        /// <param name="pkValues">主键值数组,必须和主键名对应</param>
        /// <param name="DB">数据访问对象</param>
        /// <returns></returns>
        public DataSet SelectDataSet(string fields, string tableName, string[] pkNames, object[] pkValues, CommonDB DB)
        {
            string ParaChar = GetDBParaChar(DB);
            string sqlSelect = "SELECT " + fields + " FROM " + tableName + " WHERE 1=1 ";
            IDataParameter[] paras = new IDataParameter[pkNames.Length];
            for (int i = 0; i < pkNames.Length; i++)
            {
                sqlSelect += " And " + pkNames[i] + "=" + ParaChar + pkNames[i];
                paras[i] = DB.GetParameter(ParaChar + pkNames[i], pkValues[i]);
            }
            DataSet ds = DB.ExecuteDataSet(sqlSelect, CommandType.Text, paras);
            ds.Tables[0].TableName = tableName;
            return ds;
        }

        /// <summary>
        /// 根据主键信息从数据源查询数据表到数据集中
        /// </summary>
        /// <param name="fields">字段列表</param>
        /// <param name="tableName">数据源中的表名称</param>
        /// <param name="pkNames">主键名称数组</param>
        /// <param name="pkValues">主键值数组,必须和主键名对应</param>
        /// <returns>数据集</returns>
        public DataSet SelectDataSet(string fields, string tableName, string[] pkNames, object[] pkValues)
        {
            CommonDB DB = MyDB.GetDBHelper();
            string ParaChar = GetDBParaChar(DB);
            string sqlSelect = "SELECT " + fields + " FROM " + tableName + " WHERE 1=1 ";
            IDataParameter[] paras = new IDataParameter[pkNames.Length];
            for (int i = 0; i < pkNames.Length; i++)
            {
                sqlSelect += " And " + pkNames[i] + "=" + ParaChar + pkNames[i];
                paras[i] = DB.GetParameter(ParaChar + pkNames[i], pkValues[i]);
            }
            DataSet ds = DB.ExecuteDataSet(sqlSelect, CommandType.Text, paras);
            ds.Tables[0].TableName = tableName;
            return ds;
        }

        /// <summary>
        /// 更新数据集中的字段到数据源中
        /// </summary>
        /// <param name="sDs">源数据集</param>
        /// <param name="tableName">要更新的表</param>
        /// <param name="fieldName">要更新的字段</param>
        /// <param name="fieldValue">字段的值</param>
        /// <param name="pkName">主键名称</param>
        /// <param name="DB">数据访问对象</param>
        /// <returns></returns>
        public int UpdateField(DataSet sDs, string tableName, string fieldName, object fieldValue, string pkName, CommonDB DB)
        {
            DataSet ds = sDs.Copy();
            DataTable dt = ds.Tables[tableName];
            fieldName = fieldName.ToUpper();
            pkName = pkName.ToUpper();

            for (int i = 0; i < dt.Columns.Count; i++)
            {
                string colName = dt.Columns[i].ColumnName.ToUpper();
                if (colName == fieldName || colName == pkName)
                    continue;
                dt.Columns.Remove(colName);
                i = 0;//集合元素位置可能已经迁移,所以需要重新从头开始查找
            }
            dt.PrimaryKey = new DataColumn[] { dt.Columns[pkName] };
            foreach (DataRow dr in dt.Rows)
            {
                dr[fieldName] = fieldValue;
            }

            int updCount = UpdateDataSet(ds, DB);
            return updCount;
        }

        #endregion

        #region 内部方法
        /// <summary>
        /// 获取特定数据库参数字符
        /// </summary>
        /// <param name="DB">数据库类型</param>
        /// <returns></returns>
        private static string GetDBParaChar(CommonDB DB)
        {
            return DB is Oracle ? ":" : "@";
        }

        /// <summary>
        /// 更新数据表到数据源中
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="SQL"></param>
        /// <returns></returns>
        private static int UpdateDataTable(DataTable dt, string SQL)
        {
            CommonDB DB = MyDB.GetDBHelper();
            string ParaChar = GetDBParaChar(DB);
            SQL = SQL.Replace("@@", ParaChar);
            int count = 0;
            DB.BeginTransaction();
            try
            {
                foreach (DataRow dr in dt.Rows)
                {
                    IDataParameter[] paras = new IDataParameter[dt.Columns.Count];
                    for (int i = 0; i < dt.Columns.Count; i++)
                    {
                        paras[i] = DB.GetParameter(ParaChar + dt.Columns[i].ColumnName, dr[i]);
                    }
                    count += DB.ExecuteNonQuery(SQL, CommandType.Text, paras);
                    if (DB.ErrorMessage != "")
                        throw new Exception(DB.ErrorMessage);
                }
                DB.Commit();
            }
            catch (Exception ex)
            {
                DB.Rollback();
                throw ex;
            }
            return count;

        }

        /// <summary>
        /// 自动保存数据表中的数据到数据库
        /// <remarks>更新时间:2011.11.16</remarks>
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="insertSQL"></param>
        /// <param name="updateSQL"></param>
        /// <param name="DB"></param>
        /// <returns></returns>
        private static int SaveDataTable(DataTable dt, string insertSQL, string updateSQL, CommonDB DB)
        {
            //CommonDB DB = MyDB.GetDBHelper();
            string ParaChar = GetDBParaChar(DB);
            insertSQL = insertSQL.Replace("@@", ParaChar);
            updateSQL = updateSQL.Replace("@@", ParaChar);
            int count = 0;
            DB.BeginTransaction();
            try
            {
                foreach (DataRow dr in dt.Rows)
                {
                    IDataParameter[] paras = new IDataParameter[dt.Columns.Count];
                    for (int i = 0; i < dt.Columns.Count; i++)
                    {
                        paras[i] = DB.GetParameter(ParaChar + dt.Columns[i].ColumnName, dr[i]);
                    }
                    //先更新,如果没有记录受影响再次尝试执行插入
                    int tempCount = DB.ExecuteNonQuery(updateSQL, CommandType.Text, paras);
                    if (tempCount <= 0)
                        tempCount = DB.ExecuteNonQuery(insertSQL, CommandType.Text, paras);

                    count += tempCount;

                    if (DB.ErrorMessage != "")
                        throw new Exception(DB.ErrorMessage);
                }
                DB.Commit();
            }
            catch (Exception ex)
            {
                DB.Rollback();
                throw ex;
            }
            return count;
        }

        /// <summary>
        /// 更新数据表,带数据访问对象
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="SQL"></param>
        /// <param name="DB"></param>
        /// <returns></returns>
        private int UpdateDataTable(DataTable dt, string SQL, CommonDB DB)
        {
            string ParaChar = GetDBParaChar(DB);
            SQL = SQL.Replace("@@", ParaChar);
            int count = 0;

            foreach (DataRow dr in dt.Rows)
            {
                IDataParameter[] paras = new IDataParameter[dt.Columns.Count];
                for (int i = 0; i < dt.Columns.Count; i++)
                {
                    paras[i] = DB.GetParameter(ParaChar + dt.Columns[i].ColumnName, dr[i]);
                }
                count += DB.ExecuteNonQuery(SQL, CommandType.Text, paras);
                if (DB.ErrorMessage != "")
                    throw new Exception(DB.ErrorMessage);
            }

            return count;

        }

        /// <summary>
        /// 为数据表生成更新SQL语句,参数名带@@前缀[不更新主键]
        /// </summary>
        /// <param name="dt">数据表</param>
        /// <returns></returns>
        private static string GetSqlUpdate(DataTable dt)
        {
            string sqlUpdate = "UPDATE " + dt.TableName + " SET ";
            if (dt.PrimaryKey.Length > 0)
            {
                DataColumn[] pks = dt.PrimaryKey;
                foreach (DataColumn dc in dt.Columns)
                {
                    bool isPk = false;
                    for (int i = 0; i < pks.Length; i++)
                        if (dc == pks[i])
                        {
                            isPk = true;
                            break;
                        }
                    //不更新主键
                    if (!isPk)
                        sqlUpdate += dc.ColumnName + "[email protected]@" + dc.ColumnName + ",";
                }
                sqlUpdate = sqlUpdate.TrimEnd(',') + " WHERE 1=1 ";
                foreach (DataColumn dc in dt.PrimaryKey)
                {
                    sqlUpdate += "And " + dc.ColumnName + "[email protected]@" + dc.ColumnName + ",";
                }
                sqlUpdate = sqlUpdate.TrimEnd(',');
                return sqlUpdate;

            }
            else
            {
                throw new Exception("表" + dt.TableName + "没有指定主键,无法生成Update语句!");
            }
        }

        /// <summary>
        /// 为数据表生成插入SQL语句,参数名带@@前缀
        /// </summary>
        /// <param name="dt">数据表</param>
        /// <returns></returns>
        private static string GetSqlInsert(DataTable dt)
        {
            string Items = "";
            string ItemValues = "";
            string sqlInsert = "INSERT INTO " + dt.TableName;

            foreach (DataColumn dc in dt.Columns)
            {
                Items += dc.ColumnName + ",";
                ItemValues += "@@" + dc.ColumnName + ",";
            }
            sqlInsert += "(" + Items.TrimEnd(',') + ") Values(" + ItemValues.TrimEnd(',') + ")";
            return sqlInsert;
        }

        #endregion

        public DBMSType DBMSType
        {
            get
            {
                throw new System.NotImplementedException();
            }
            set
            {
            }
        }

        public SQLPage SQLPage
        {
            get
            {
                throw new System.NotImplementedException();
            }
            set
            {
            }
        }

    }
}
时间: 2024-08-06 20:08:12

修改PDF.NET SOD源代码以支持加密的数据库连接字符串的相关文章

一年之计在于春,2015开篇:PDF.NET SOD Ver 5.1完全开源

前言: 自从我2014年下半年到现在所在的某电商公司工作后,忙于工作,一直没有写个一篇博客,甚至连14年股票市场的牛市都错过了,现在马上要过年了,而今天又是立春节气,如果再不动手,那么明年这个无春的年,也就不适合写博客了,呵呵,这仅仅对我而言.一年之计在于春,我得重新开始写一些博客,想写的很多,那么这开篇为了一个好兆头,就写PDF.NET SOD Ver 5.1完全开源 的事情吧. 框架简介: “PDF.NET框架”全称是“PWMIS数据开发框架”(有关名字的由来请看官网http://www.p

PDF.NET SOD 开源框架红包派送活动 &amp;&amp; 新手快速入门指引

一.框架的由来  快速入门 有关框架的更多信息,请看框架官方主页! 本套框架的思想是借鉴Java平台的Hibernate 和 iBatis 而来,兼有ORM和SQL-MAP的特性,同时还参考了后来.NET的LINQ(本框架成型于2006年,当时还未听说过LINQ)使用风格,设计了OQL查询表达式.本框架的设计思想是通用的,完全可以移植到Java 平台,现在只提供了.NET平台的实现,暂且将本框架命名为 PDF.NET 从2013.10.1日起,原PDF.NET 将更名为 SOD one SQL-

pdf文件怎么修改 修改PDF文件的两种方法

都说PDF格式的文件不能修改,我就呵呵了!不管你们信不信,反正我是不信.因为我会修改PDF文件,并且方法还不止一种.想知道我是怎么修改PDF文件的吗?下面我就告诉大家修改PDF文件的两种方法. 方法一 1.方法一就是将PDF文件转换成一种可容易编辑的文档,如:word.excel.ppt等格式,然后再进行编辑,编辑好后再将其转换成PDF格式,是不是很简单!具体是该如何转换的,下面有详细教程. 2.下载一个PDF转换器,并将它安装在电脑上.工具最好是支持双向转换的那种,如:http://www.x

怎么样修改PDF文件-PDF文件修改教程

怎么样修改PDF文件-PDF文件修改教程 现在网络上共享资源非常多,大家写个文章找个答案都会到网上进行一番搜索,可是网络上的很多资料都是PDF格式,或者直接是图片,对于这种情况,很不利于用户对资料的有效使用,有什么方法可以将pdf文件进行修改呢? 经过小编的网络上众多文字识别工具的测试,终于找到一款文字提取效果非常好的工具——捷速ocr文字识别软件. 一.工具下载及安装  1.捷速ocr文字识别软件 v2.0 免费版 2.安装过程比较简单,每一步都有相应的提示,用户只需三步即可轻松完成. 二.运

基于正则的INI读写工具类,支持加密解密

看到这个标题,有人会问,现在都用xml做配置文件了,谁还用INI文件啊!下面来简单对比一下xml和ini: 1.XML功能强大表达能力强,同时扩展性好. 2.它的主要优势是异构平台的整合.通讯. 3.缺点主要是使用复杂,运行库占用的资源较多. 4.如果多个程序进行数据交换或是跨平台通讯则使用功能强大的XML: 5.INI虽表达能力不强,但是简单实用,接口方便.如果是用于应用程序的配置INI文件就够了. 至于哪个更好,应该用哪个,可以根据自己爱好和需求.个人感觉INI文件操作简单,就是读取文件,处

怎么修改PDF文档内容

要问目前最为流行的一种电子文档是什么,那就非PDF莫属了.PDF与其他格式的文件相比,有着诸多的优点,也更适合我们进行阅读.但我们如果想要修改PDF文档的话,就并不是那么直接的事情了.我们需要使用专门的编辑软件,才能对其进行编辑.而选择合适的软件,也是十分重要的. 捷速PDF修改器可以对PDF文件进行图片替换.文字修改.绘画标注.页面旋转.输出与打印等.可任意编辑PDF文档中文本,图像以及多媒体文件,支持PDF新建文档,让新的创意快速跃然纸上,具有完美出色的pdf阅读效果,自定义页面缩放与自适配

怎样编辑和修改pdf格式文档

由Adobe公司开发的PDF格式文件具有良好的跨平台优势,能够最大程度保持文档的版面格式的阅读的便利性,但也因为这样,给我们编辑和修改带来了很多问题,在日常工作中,可能很多人都遇到过需要对一份PDF文件进行编辑修改却无从下手的情况,下面读者就教大家如何编辑和修改PDF格式文件. PDF阅读器软件很多,如常见的Adobe reader等,这些软件体积也都比较小巧,但是却不能对PDF文件进行编辑或者编辑功能较单一.捷速PDF编辑器是PDF编辑软件,体积小巧,但是编辑功能确实最强大的,支持修改编辑PD

怎么直接编辑修改PDF文件内容

现在的一些办公文档普遍都是PDF格式,很多文档在传递时也都会转成PDF,但这种格式文件有一个不便之处,就是编辑处理起来没有有Word文档那么流畅顺手.对此,很多初涉职场或是初用PDF文件的人都不怎么会运用这个格式的文档.那么PDF文件该怎么修改内容呢? 不是所有pdf文件都是可以随意修改的,有些pdf扫描文件就不能像普通文档一样修改文字了,因为扫描的形成的文件内容都是图片格式.设置了加密保护的文档在打开时也是需要输入密码后才可以正常编辑. 要用pdf编辑工具打开pdf文件,Adobe Reade

如何修改pdf格式文件

很多人只看的得到pdf文件阅读起来很高大上,但是不知道实际上pdf文件也是可以编辑和 修改的,怎么阳曲修改呢?那么小编呢分享两种很实用的方法,供大家参考. 下面是两种修改的方法及步骤: 1.通过转换格式修改PDF格式文件 使用专业的格式转换器将PDF文件转换成word文档编辑,编辑好后再转换回来.这种方法 适合习惯使用word.Excel等办公软件的人. 具体的操作方法: 首先,打开迅捷PDF转换器,选择转换模式,例如将PDF文件转换成Word文档,点击图标勾 选"文件转word"即可