最近在開發一款考勤系統,遇到一個問題,就是考勤狀態查詢,常用的狀態有:遲到、早退、補簽、補簽同意、請假、曠工、漏打下班卡等。
這些狀態不是單獨存在的,有時候一個用戶可能既遲到,又早退,還申請了補簽,這時候只用一個狀態表示,就無法准確記錄考勤狀態。
如果說組合起來使用Like模糊查詢,也不失為一種常用方法,但感覺效率會比較低,代碼也會比較繁瑣。
於是乎,一種新的記錄考勤狀態的方法被應用。
首先,要在數據里創建一個集合,如下圖所示。
這里的Num建議使用2的N次方,這樣任意數據相或,不會出現重復數據。
此數據建立之后,就是表字段賦值問題,我的代碼是這樣寫的。
具體的代碼如下:
/// <summary> /// 獲取累加的簽到明細狀態值 /// </summary> /// <param name="detailStatus"></param> /// <param name="status"></param> /// <returns></returns> public static int GetCheckOnDetailStatus(int detailStatus, String status) { CheckOnDetailStatusRepository statusRepository = new CheckOnDetailStatusRepository(); var statusModel = statusRepository.GetCheckOnStatus(status); if (statusModel != null) { return statusModel.Num | detailStatus; } return detailStatus; }
這里使用到了“或”運算,所只管累加,不會重復的,請放心使用。
賦值之后,會涉及更新狀態的問題,我的代碼是這樣寫的。
//刪除早退狀態,最后一個參數,可以替換為你想要的狀態
todayCheckOn.DatailStatus = Cigna.Attendance.Business.Common.ReplaceCheckOnDetailStatus(todayCheckOn.DatailStatus, "早退", "");
具體代碼如下:
/// <summary> /// 更新替換簽到明細狀態值 /// </summary> /// <param name="detailStatus"></param> /// <param name="status"></param> /// <returns></returns> public static int ReplaceCheckOnDetailStatus(int detailStatus, String oldStatus,String newStatus) { CheckOnDetailStatusRepository statusRepository = new CheckOnDetailStatusRepository(); var statusOld = statusRepository.GetCheckOnStatus(oldStatus); if (String.IsNullOrEmpty(newStatus))//更新為空 { if (statusOld != null) { return (detailStatus ^ statusOld.Num); } else { return detailStatus; } } var statusNew = statusRepository.GetCheckOnStatus(newStatus); if (statusOld != null && statusNew !=null) { return (detailStatus ^ statusOld.Num) | statusNew.Num ; } return detailStatus; }
這樣對狀態的新增、更新、刪除就都有了,接下來就是查詢了。
舉個例子,我要查詢某狀態的數據,就可以使用如下Sql:
if (condition.DatailStatus > 0) { condtionStr += String.Format( " AND c.DatailStatus & {0} > 0",condition.DatailStatus); }
至此,收工、回家。