Monday, November 14, 2011

[C#] 可以Rollback的Transaction與TransactionScope

可以RollbackTransactionTransactionScope
最近才把Transaction的機制加到我的查詢工具裡,來控制CommitRollback
之前沒有考慮作個CommitRollback的原因是,怕自己會去依賴Rollback。 所以我作資料異動時,一定確認好異動的筆數,然後備份表格,最後才真的執行SQL
如果依賴Rollback,到時候囉不回去... 就囧了。
上次主管提到Transaction,想想也該來研究一下,當然就拿EzOracle查詢工具來測試。




我把原本的Query函式稍作調整
public static string DB_ExecNonQuery_Trans(ref OracleTransaction transaction, string nSql)
 {
            if (Conn.State == ConnectionState.Closed) return "失敗=資料庫未連結";
            try
            {
               /*
                OracleCommand cmdGeneral = new OracleCommand(nSql, Conn );
                double Result = cmdGeneral.ExecuteNonQuery();
               */
                if (transaction == null//transactionnull時,才需要重新指定,否則會error
                {
                    transaction = Conn.BeginTransaction(System.Data.IsolationLevel.ReadCommitted);
                }
               OracleCommand command = Conn.CreateCommand();
               //指定commandTransactiontransaction
                command.Transaction = transaction;

                command.CommandText = nSql;
                double Result = command.ExecuteNonQuery();

                return "成功=" + Result.ToString();
            }
            catch (Exception ex)
            {
                return "失敗=" + ex.Message;
            }
}


其中灰底的部分是原本的程式。
另外要注意,因為這個函式可以重複被呼叫,(也就是,Transaction可以包多個異動的sql
所以重複呼叫時要判斷
if (transaction == null再去BeginTransaction,否則會錯誤。

最麻煩的是… 要放個CommitRollback的功能按鈕,還有判斷是否指令已被Commit… 這邊才是最多功的地方阿 Orz


[C#] 如何取消關閉WinForm

這是今天的小發現~
按下關閉視窗的X鈕,還可以取消關閉呢 :)

只要在Closing事件中,把CancelEventArgs 的 e.Cancel 設定成 true 就可以了~


參考:http://msdn.microsoft.com/zh-tw/library/system.windows.window.closing(v=vs.90).aspx

void DataWindow_Closing(object sender, CancelEventArgs e)
        {
             // If user doesn't want to close, cancel closure
             e.Cancel = true;
        }

[Android]廣告收入相關





[C#] Delegate Event (1)

Delegate Event

目標:
實務上遇到需要計算每家廠商的交易手續費,但是每家廠商計算手續費的方法不同,所以利用Delegate event去指定各家廠商的交易手續費算法(Method)。

一、                Windows Form專案來作範例
1.          專案內容:


2.          Merchant\IMerchant.cs … 廠商Interface
Merchant\CMerchant.cs ...
廠商Class
CalFeeMethod.cs ...
手續費計算方法
Form1.cs
3.          執行畫面

二、                IMerchant.cs
1.          程式碼

public delegate void CalFeeHandler(double dFee_Pt, double dNum);

       public interface IMerchant
       {
         //廠商代號
         String Merchant_No {get; set; }
         //手續費
         double Fee_Pt { get; set;  }
         //計算手續費的事件
         event CalFeeHandler CalFee;
       }

2.          →宣告一個delegateCalFeeHandler
→在介面指定一個delegate eventCalFee

 
三、                CMerchant.cs
1.          程式碼
public class CMerchant : IMerchant
    {
        String sMerchant_No;  //廠商代號
        double dFee_Pt;  //手續費
        public event CalFeeHandler CalFee;   //計算手續費的事件

        /* 建構子 */
        public CMerchant(String m_id)
        {
            sMerchant_No = m_id;
        }

        /* Merchant_No */
        public String Merchant_No
        { //Get and Set … 省略 }

        /* Fee_Pt */
        public double Fee_Pt
        { //Get and Set … 省略 }

        /* 觸發CalFee這個Event */
        public void Print_Fee(double dNum)
        {
            if (CalFee == null//未指定手續費時...
            {
                Console.WriteLine("未指定手續費計算事件!");
            }
            else  // CalFee 這個delegate event計算手續費
            {
                CalFee(dFee_Pt, dNum);
            }
        }
    }

2.          重點是Print_Fee這個方法因為在用這個class你可以指定event所對應的方法,卻不能直接呼叫它。  所以必須用呼叫Print_Fee來觸發CalFee這個事件。
另外CalFee帶入的值必須和宣告delegate當時的帶入值型態和數量一致。


四、                CalFeeMethod.cs
1.          程式碼
public class CalFeeMethod
    {
        /* 手續費 = 交易筆數*手續費趴數 */
        public static void CalFee_by_TransCnt(double dFee_Pt, double dCnt)
        {
            double dFee = dCnt * dFee_Pt;
            Console.WriteLine("手續費 = 交易筆數*手續費%=" + dFee.ToString());
        }

        /* 手續費 = 交易金額*手續費趴數/100 */
        public static void CalFee_by_TransAmt(double dFee_Pt, double dAmt)
        {
            double dFee = dAmt * dFee_Pt / 100;
            Console.WriteLine("手續費 = 交易金額*手續費%/100" + dFee.ToString());
        }
    }
2.          這裡就是放我們要計算手續費演算法的地方。 只要注意這些方法的回傳值型態和傳入值跟delegate event相同就好了。

五、                Form1.cs
1.          接下來就是直接拿來用了,底下用一個ListBox放三家廠商的代號,當按下「算手續費」按鈕時,就會計算各家廠商的手續費。
2.          程式碼
foreach (String sM_No in lb_Mno.Items)
            {
                CMerchant myMerchant = new CMerchant(sM_No);
               
                Console.WriteLine("廠商代號:" + myMerchant.Merchant_No);

                switch (sM_No)
                {
                    case "123456":
                        myMerchant.Fee_Pt = 0.8;
                        myMerchant.CalFee += CalFeeMethod.CalFee_by_TransCnt;
                        break;
                    case "888888":
                        myMerchant.Fee_Pt = 0.5;
                        myMerchant.CalFee += CalFeeMethod.CalFee_by_TransAmt;
                        break;
                    default:
                        myMerchant.Fee_Pt = 0;
                        break;
                }

                //列印手續費
                myMerchant.Print_Fee(1000);
                Console.WriteLine("");
            }
3.            myMerchant.CalFee += CalFeeMethod.CalFee_by_TransCnt; 去指定delegate event的方法。
  因為333333這家廠商我沒有指定計算手續費的方法,所以會顯示以下結果….
 
特約機構代號:123456
手續費 = 交易筆數*手續費%=800

特約機構代號:888888
手續費 = 交易金額*手續費%/1005

特約機構代號:333333
未指定手續費計算事件!




六、                利用delegate event,未來有新廠商的時候,我只要讓程式知道這家新廠商是用哪一種算手續費的方法,不用另外在程式作判斷了~ 雖然一開始寫有點辛苦,後面倒是比較好維護