一步一步建立我的MIS系統(1):分析

       MIS系統,就是管理信息系統,是企業管理思想的體現。一個MIS系統做得好不好,不僅在於IT部門的水平有多高,更在於一個企業的管理先不先進,規不規範,企業的高層對MIS系統得認識有多深。

      當然,有一個好的CIO,一個好的系統分析員,一個好的架構師,一個好的數據設計師,3~5個訓練有素,基本功過硬的程序員(至少要能熟練運用數組,鏈表,隊列,堆棧,要知道遞規,知道怎樣把遞規算法改爲非遞規算法,知道樹,二叉查找樹,知道窮舉法,貪婪法等),再加上一個美工,那是再好不過了。可惜,大部分的企業沒有這些人,或者這些人不全(至少我知道的企業如此,軟件公司除外),都是一個人頂幾個人用。像我,一個人既是系統分析員(直接和用戶打交道,搞清楚他們的需求),又是架構師(架構不好,那以後的修改可是非常痛苦的,不要認爲用戶的要求的是不變,有時候,一個星期,他就要變3次),又是做數據設計(搞MIS系統,如果不熟悉SQL,那可說不過去),又是編碼(分內之事),又作界面設計(雖然難看,但是沒人,你就得抗),系統測試(你寫的程序你不測試,誰測試?),有時還得給人裝裝機,換換硒鼓,調調IP。所以工作了好幾年,但水平一直提不高,也就是弄弄數據庫,見幾個表,然後打開Delphi,新建一個表單,拉幾個比如DbEdit之類的東東,在設置一下DataSource,放幾個按鈕,寫幾行Insert,Edit,Post之類的代碼。說是高級打字員,一點也不爲過。

      就這樣敲了幾年的Begin,End,Insert,Edit,Post,Select,update,delete,發現了一個規律,就是我每天辛辛苦苦敲的這些東東,其實完全可以敲一次就可以了,其他地方拉過就是了,不就是對數據的增,刪,改麼?哪管你審覈,覈准,還不就是對數據中一個字段的修改?什麼權限不權限,還不就是設定一下,讓你看不看得到某個字段的內容?這樣一想,居然覺得自己以前好傻。

    所有的這些,最終都是通過SQL語句實現的,整個過程可以這樣描述。

    首先,用戶開始使用系統,於是我根據他/她的用戶名select field1,field2,... from table where .... order by ....,然後用戶開始新增或修改數據,新增時,我 insert into table(field1,field2,field3....) values(value1,value2,value3...),修改時,我update table set field1=value1,field2=value2...where ....刪除時,我delete from table where ....

   再分析,發現這些select,update,delete們,也有共同的特點,就是都是由動作,對象,條件組成,比如,select * from table where conditon1 order by sequence,update table set field1=value where condition,delete from table where condition。

   至於相關的業務流程,無非就在Insert,update,delete之前作判斷,是否exists某種condition,如果存在,就再做相應的insert,update或delete,或者讓這些Insert,update,delete動作不被執行。

   如果將這些功能封裝爲一個或幾個類,其他地方只要調用這個類或者幾個類,那不就省事多了?說幹就幹,經過兩天的冥思苦想,基於SQL Server 2005,C#2.0,寫了下面的幾行代碼,我把它做爲一個文件,DBWR.cs。

//
//Privileges.cs
//
namespace EwEAI.Business.Interfaces.IT
{

   //
   //權限定義
   //
    public enum PrivilegeType
    {
        PrivilegeNone,

        GrantInsert = 1,
        DenyInsert = 2,

        GrantUpdate = 11,
        DenyUpdate = 12,

        GrantDelete = 21,
        DenyDelete = 22,

        GrantRun = 31,
        DenyRun = 32,

        GrantPrint = 41,
        DenyPrint = 42,

        GrantSelect = 91,
        DenySelect = 92
    }
}

//
//DBWR.cs
//

//#define Debug

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

using EwEAI.Business.Interfaces.IT;


namespace EwEAI.Data
{
    /// <summary>
    /// DBWR:數據讀寫類
    /// </summary>
    public class DBWR
    {

        #region 構造函數

        private DBWR()
        {
            InitSetting();
            _ConnectionString = GetDbCononectionString();
        }

        private void InitSetting()
        {
            DbSetting.ReadXml(@"../settings/DbSettings.xml");
        }
        private DataSet DbSetting = new DataSet("DbSetting");

        private string GetDbCononectionString()
        {
            DataTable table = DbSetting.Tables["DataBase"];
            table.DefaultView.Sort = "Name ASC";
            int index=table.DefaultView.Find("DBConStr");
            if (index == -1)
                return null;

            return table.DefaultView[index]["Value"].ToString();          
        }


        /// <summary>
        /// 數據讀寫模塊的唯一實例
        /// </summary>
        public static DBWR Instance
        {
            get
            {
                if (_instance == null)
                    _instance = new DBWR();
                return _instance;
            }
        }
        private static DBWR _instance = null;


        #endregion


        #region 數據庫聯接

        /// <summary>
        /// 數據庫連接字符串
        /// </summary>

        public string ConnectionString
        {
            get
            {
#if Debug
                return "Data Source=EW-CLIENT;Initial Catalog=EwEAI;User Id=sa;password=yahong;Pooling=true;Max Pool Size=8;Min Pool Size=3";
#else
               // return System.Configuration.ConfigurationManager.AppSettings["DBConStr"];
                //return System.Configuration.ConfigurationSettings.AppSettings["DBConStr"];

                return _ConnectionString;
#endif
            }
        }
        private string _ConnectionString = null;

        /// <summary>
        /// 數據庫連接
        /// </summary>
        public SqlConnection Connection
        {
            get
            {
                return new SqlConnection(ConnectionString);
            }
        }


        #endregion


        #region 數據讀寫


        /// <summary>
        /// 構建某個表的選擇列表
        /// </summary>
        /// <param name="User"></param>
        /// <param name="tableName"></param>
        /// <param name="Where"></param>
        /// <param name="Order"></param>
        /// <param name="ColList"></param>
        /// <returns></returns>
        ///
        public string BuildSelectSQL(string User, string tableName, string Where, string Order,
               string[] ColList/*null返回所有字段*/)
        {
            StringBuilder Result = new StringBuilder("");

            //表判定
            string TableSQL = "select 1 from TablePrivileges where tableName='" + tableName + "'"
                + " and UserName in(select UserName from UserTree('" + User + "',1))"
                + "  and SelectPrivilege=" + ((int)PrivilegeType.DenySelect).ToString();

            object isDeny = this.GetSingleValue(TableSQL);
            if (isDeny != null)
                return null;

            DataTable ColTable = GetFieldList(tableName, User);
            if (ColTable == null)
                return null;
            if (ColTable.Rows.Count == 0)
                return null;

            //字段判定
            string DenyString = "select FieldName from FieldPrivileges where tableName='" + tableName + "'"
                + " and UserName in(select UserName from UserTree('" + User + "',1))"
                + " and SelectPrivilege=" + ((int)PrivilegeType.DenySelect).ToString();

            DataTable DenyFieldsTable = this.ReadData(DenyString);
            Hashtable DenyFields = new Hashtable(30);
            if (DenyFieldsTable != null)
            {
                foreach (DataRow dr in DenyFieldsTable.Rows)
                    DenyFields.Add(dr[0].ToString(), dr[0].ToString());

                DenyFieldsTable.Dispose();
            }

            Result.Append(" select ");
            int FieldCount = 0;
            for (int i = 0; i < ColTable.Rows.Count; i++)
            {
                string FieldName = ColTable.Rows[i][0].ToString();
                if (DenyFields.Contains(FieldName))
                    continue;

                //如果只返回部分字段
                if (ColList != null)
                {
                    int j = 0;
                    for (; j < ColList.Length; j++)
                    {
                        if (FieldName == ColList[j])
                            break;
                    }
                    if (j == ColList.Length)
                        continue;
                }

                Result.Append(FieldName);
                FieldCount++;
                if (ColList != null)
                    if (FieldCount == ColList.Length)
                        break;

                if (i < ColTable.Rows.Count - 1)
                    Result.Append(",");
            }
            Result.Append(" from ");
            Result.Append(tableName);
            Result.Append(" ");
            Result.Append(Where);
            Result.Append(" ");
            if (Order != null && Order != "")
            {
                Result.Append(" Order by ");
                Result.Append(Order);
            }

            ColTable.Dispose();
            return Result.ToString();
        }


        /// <summary>
        /// 提取某個表的可以選擇字段
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="User"></param>
        /// <returns></returns>
        private DataTable GetFieldList(string tableName, string User)
        {
            string ASQL = "select FieldName,(select Seq from Fields where tableName='"
                      + tableName + "' and FieldName=O.FieldName)Seq from FieldPrivileges O"
                + " where UserName in (select UserName from UserTree('" + User + "',1))"
                + "   and TableName='" + tableName + "'"
                + "   and FieldName in(select FieldName from Fields where IsUserDefined=0)"
                + " order by Seq";

            return this.ReadData(ASQL);
        }

        public void ExecSQL(string SQL)
        {
            SqlConnection con = Connection;
            try
            {
                con.Open();
                SqlCommand cmd = new SqlCommand(SQL, con);
                cmd.ExecuteNonQuery();

                cmd.Dispose();

            }
            finally
            {
                con.Close();
                con.Dispose();
                con = null;
            }

        }

        public DataTable ReadData(string SQL)
        {
            SqlConnection con = Connection;
            try
            {
                DataTable table = new DataTable();

                SqlDataAdapter adapter = new SqlDataAdapter(SQL, con);
                adapter.FillSchema(table, SchemaType.Source);
                adapter.Fill(table);

                adapter.Dispose();
                return table;

            }
            finally
            {
                con.Dispose();
            }
        }

        public DataTable ReadData(string SQL,ref DataTable table)
        {
            SqlConnection con = Connection;
            try
            {
                SqlDataAdapter adapter = new SqlDataAdapter(SQL, con);
                adapter.FillSchema(table, SchemaType.Source);
                adapter.Fill(table);

                adapter.Dispose();

                return table;
            }
            finally
            {
                con.Dispose();
            }                
        }

        public DataTable GetStruct(string SQL)
        {
            SqlConnection con = Connection;
            try
            {
                DataTable Result = new DataTable();
                SqlDataAdapter adapter = new SqlDataAdapter(SQL, con);
                adapter.FillSchema(Result, SchemaType.Source);

                adapter.Dispose();

                return Result;
            }
            finally
            {
                con.Dispose();
            }
        }


        public object GetSingleValue(string SQL)
        {
            SqlConnection con = Connection;
            try
            {
                con.Open();
                SqlCommand cmd = new SqlCommand(SQL, con);
                object Result = cmd.ExecuteScalar();
                cmd.Dispose();

                if (Result is DBNull)
                    return null;

                return Result;
            }
            finally
            {
                con.Dispose();
            }
        }


        public string Update(string ASQL, DataTable table)
        {
            string Result = "";

            SqlConnection con = Connection;
            SqlTransaction action = null;
            try
            {
                using (SqlDataAdapter adapter = new SqlDataAdapter(ASQL, con))
                {
                    using (SqlCommandBuilder cb = new SqlCommandBuilder(adapter))
                    {
                        con.Open();
                        cb.RefreshSchema();
                        adapter.UpdateCommand = cb.GetUpdateCommand();
                        adapter.DeleteCommand = cb.GetDeleteCommand();
                        adapter.InsertCommand = cb.GetInsertCommand();

                        action = con.BeginTransaction();

                        adapter.UpdateCommand.Transaction = action;
                        adapter.DeleteCommand.Transaction = action;
                        adapter.InsertCommand.Transaction = action;

                        adapter.Update(table);
                        action.Commit();
                    }
                }
            }
            catch (Exception e)
            {
                Result = e.Message;
                action.Rollback();
            }
            finally
            {
                con.Dispose();
                action.Dispose();
                action = null;
            }

            return Result;
        }

        public string Update(string ASQL, DataRow row)
        {
            string Result = null;
            SqlConnection con = Connection;
            try
            {
                using (SqlDataAdapter adapter = new SqlDataAdapter(ASQL, con))
                {
                    using (SqlCommandBuilder cb = new SqlCommandBuilder(adapter))
                    {
                        adapter.Update(new DataRow[] { row });
                    }
                }
            }
            catch (Exception e)
            {
                Result = e.Message;
            }
            finally
            {
                con.Dispose();
            }

            return Result;
        }

        private Hashtable GetAdapter(Hashtable SQLS,SqlConnection con)
        {
            Hashtable Result = new Hashtable(SQLS.Count);
            foreach (string SQL in SQLS.Values)
            {
                SqlDataAdapter adapter = new SqlDataAdapter(SQL, con);
                SqlCommandBuilder cb = new SqlCommandBuilder(adapter);

                adapter.UpdateCommand = cb.GetUpdateCommand();
                adapter.DeleteCommand = cb.GetDeleteCommand();
                adapter.InsertCommand = cb.GetInsertCommand();

                Result.Add(SQL, adapter);
            }

            return Result;
        }


        public string Update(DataSet businessData,Hashtable SQLS)
        {
            SqlConnection con = Connection;           
            SqlTransaction action = null;

            Hashtable Adapters = new Hashtable();

            try
            {
                Adapters=GetAdapter(SQLS,con);

                con.Open();
                action = con.BeginTransaction();
    
                foreach (DataTable table in businessData.Tables)
                {
                    try
                    {
                        if (table.GetChanges() == null)
                            continue;

                        string SQL = SQLS[table.TableName].ToString();

                        SqlDataAdapter adapter = (SqlDataAdapter)Adapters[SQL];
                        adapter.InsertCommand.Transaction = action;
                        adapter.UpdateCommand.Transaction = action;
                        adapter.DeleteCommand.Transaction = action;

                        adapter.Update(table.GetChanges());
                    }
                    catch (Exception cex)
                    {
                        if (!(cex is DBConcurrencyException))
                        {
                            throw cex;
                        }
                    }
                }            
              
                action.Commit();
            }
            catch (Exception e)
            {                
                action.Rollback();
                return e.Message;
            }
            finally
            {
                foreach (SqlDataAdapter adater in Adapters.Values)
                    adater.Dispose();
                Adapters.Clear();

                con.Dispose();
                action.Dispose();
                action = null;
            }
            return null;

        }

        #endregion


    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章