1. 程式人生 > >Linq 多個DataTable表關聯查詢,實現考勤統計。

Linq 多個DataTable表關聯查詢,實現考勤統計。

最近在做考勤系統時,由於不同的分公司的資料來源在不同的伺服器上,關聯查詢比較麻煩,因此想到了用Linq實現關聯查詢。

思路:查詢各個考勤資訊的dataTable,然後用Linq實現DataTable的多張表左關聯查詢。貼出來,與大家分享。

程式碼實現如下:

1.View顯示:

    /// <summary>
    /// 考勤統計表-用於工資核算
    /// </summary>
    public class AttendanceCountVM
    {
        [Key]
        public Guid Guid { get; set; }
        [Display(Name = "姓名")]
        public string Name { get; set; } //姓名
        [Display(Name = "部門")]
        public string Department { get; set; } //部門
        [Display(Name = @"遲到/早退大於30分鐘/次")]
        public int LateMore { get; set; } //遲到/早退大於30分鐘/次
        [Display(Name = @"遲到/早退小於30分鐘/次")]
        public int LateLess { get; set; } //遲到/早退小於30分鐘/次
        [Display(Name = "單次打卡(上班未打卡)/次")]
        public int SignIn { get; set; } //單次打卡(上班未打卡)/次
        [Display(Name = "單次打卡(下班未打卡)/次")]
        public int SignOut { get; set; } //單次打卡(下班未打卡)/次
        [Display(Name = "未打卡/次")]
        public int SignNo { get; set; } //未打卡/次
        [Display(Name = "實際應出勤(H)")]
        public int AttendanceTime { get; set; } //實際應出勤(H)
        [Display(Name = "出差(H)")]
        public int OutSide { get; set; } //出差(H)
        [Display(Name = "事假(H)")]
        public int AffairLeave { get; set; } //事假(H)
        [Display(Name = "病假(H)")]
        public int SickLeave { get; set; } //病假(H)
        [Display(Name = "產前病事假(H)")]
        public int AntenatalLeave { get; set; } //產前病事假(H)
        [Display(Name = "產假或護理假(H)")]
        public int MaternityLeave { get; set; } //產假或護理假(H)
        [Display(Name = "婚假(H)")]
        public int MaritalLeave { get; set; } //婚假(H)
        [Display(Name = "喪假(H)")]
        public int FuneralLeave { get; set; } //喪假(H)
        [Display(Name = "年假(H)")]
        public int AnnualLeave { get; set; } //年假(H)
        [Display(Name = "公假(H)")]
        public int PublicHoliday { get; set; } //公假(H)
        [Display(Name = "其他(H)")]
        public int Others { get; set; } //其他(H)
        [Display(Name = "調休(H)")]
        public int BreakOff { get; set; } //調休(H)
        [Display(Name = "平時延長(H)")]
        public int PeacetimeExtension { get; set; } //平時延長(H)
        [Display(Name = "休息日(H)")]
        public int RestDay { get; set; } //休息日(H)
        [Display(Name = "法定節假日(H)")]
        public int LegalHolidays { get; set; } //法定節假日(H)
        [Display(Name = "加班摺合調休時間(H)")]
        public int TotalHours { get; set; } //加班摺合調休時間(H)

    }

Linq實現: 

        public List<AttendanceCountVM> GetAttendanceList(string StartDate, string EndDate, string Employee)
        {
            DataTable dtEmployee = CommUtils.GetUserList("", Employee);
            DataTable dtSignRecord = this.GetSignRecord(StartDate, EndDate);
            DataTable dtLeaveRecord = this.GetLeaveRecord(StartDate, EndDate);
            DataTable dtOvertimeRecord = this.GetOverTimeRecord(StartDate, EndDate);
            DataTable dtOutSideRecord = this.GetOutSideRecord(StartDate, EndDate);
            //List<AttendanceCountVM> list = (from m in dtEmployee.AsEnumerable()
            //                                join n in dtSignRecord.AsEnumerable()
            //                             on m.Field<string>("UNAME") equals
            //                                n.Field<string>("emp_fname") into mn
            //                                from x in mn.DefaultIfEmpty() 

            //                                select new AttendanceCountVM
            //                                {
            //                                    Name = m.Field<string>("UNAME").ToString(),
            //                                    Department = m.Field<string>("OName").ToString(),
            //                                }).ToList();
            var list = (from m in dtEmployee.AsEnumerable()
                        join n in dtSignRecord.AsEnumerable()
                         on m.Field<string>("UNAME") equals n.Field<string>("emp_fname") into mn
                        from x in mn.DefaultIfEmpty()
                        join o in dtOutSideRecord.AsEnumerable() on m.Field<decimal>("UserID") equals o.Field<Int32>("ApplyUserID") into mo
                        from y in mo.DefaultIfEmpty()
                        join p in dtLeaveRecord.AsEnumerable() on m.Field<decimal>("UserID") equals p.Field<Int32>("ApplyUserID") into mp
                        from z in mp.DefaultIfEmpty()
                        join q in dtOvertimeRecord.AsEnumerable() on m.Field<decimal>("UserID") equals q.Field<Int32>("ApplyUserID") into mq
                        from zx in mq.DefaultIfEmpty()
                        select new AttendanceCountVM
                                            {
                                                Guid = Guid.NewGuid(),
                                                Name = m.Field<string>("UNAME").ToString(),
                                                Department = m.Field<string>("OName").ToString(),
                                                LateMore = x == null ? 0 : x.Field<Int32>("遲到或早退30分鐘以上"),
                                                LateLess = x == null ? 0 : x.Field<Int32>("遲到或早退30分鐘以內"),
                                                SignIn = x == null ? 0 : x.Field<Int32>("上班未打卡"),
                                                SignOut = x == null ? 0 : x.Field<Int32>("下班未打卡"),
                                                SignNo = 0,//n.Field<string>("").ToString(),
                                                AttendanceTime = 176,// m.Field<string>("").ToString(),
                                                OutSide = y == null ? 0 : y.Field<Int32>("TotalOutSide"),
                                                AffairLeave = z == null ? 0 : z.Field<Int32>("事假"),
                                                SickLeave = z == null ? 0 : z.Field<Int32>("病假"),
                                                AntenatalLeave = z == null ? 0 : z.Field<Int32>("產前病事假"),
                                                MaternityLeave = z == null ? 0 : z.Field<Int32>("產假或護理假"),
                                                MaritalLeave = z == null ? 0 : z.Field<Int32>("婚假"),
                                                FuneralLeave = z == null ? 0 : z.Field<Int32>("喪假"),
                                                AnnualLeave = z == null ? 0 : z.Field<Int32>("年假"),
                                                PublicHoliday = z == null ? 0 : z.Field<Int32>("公假"),
                                                Others = z == null ? 0 : z.Field<Int32>("其他"),
                                                BreakOff = z == null ? 0 : z.Field<Int32>("調休"),
                                                PeacetimeExtension = zx == null ? 0 : zx.Field<Int32>("平時延長"),
                                                RestDay = zx == null ? 0 : zx.Field<Int32>("休息日"),
                                                LegalHolidays = zx == null ? 0 : zx.Field<Int32>("法定節假日"),
                                                TotalHours = 0,// m.Field<Int32>("").ToString(),
                                            }).ToList();

            #region
            // m.ItemArray.Concat(n.ItemArray.Skip(1)).Concat(o.ItemArray.Skip(1)).Concat(p.ItemArray.Skip(1)).Concat(q.ItemArray.Skip(1)).ToList());

            //List<AttendanceCountVM> list = new List<AttendanceCountVM>();
            //foreach (var item in items)
            //{
            //    list.Add(new AttendanceCountVM
            //    {
            //        Guid = item.Guid,
            //        Name = item.Name,
            //        Department = item.Department,
            //        LateMore = item.LateMore,
            //        LateLess = item.LateLess,
            //        SignIn = item.SignIn,
            //        SignOut = int.Parse(item[7].ToString()),
            //        SignNo = int.Parse(item[7].ToString()),
            //        AttendanceTime = int.Parse(item[7].ToString()),
            //        OutSide = int.Parse(item[8].ToString()),
            //        AffairLeave = int.Parse(item[10].ToString()),
            //        SickLeave = int.Parse(item[11].ToString()),
            //        AntenatalLeave = int.Parse(item[12].ToString()),
            //        MaritalLeave = int.Parse(item[13].ToString()),
            //        FuneralLeave = int.Parse(item[14].ToString()),
            //        AnnualLeave = int.Parse(item[15].ToString()),
            //        PublicHoliday = int.Parse(item[16].ToString()),
            //        Others = int.Parse(item[17].ToString()),
            //        BreakOff = int.Parse(item[18].ToString()),
            //        PeacetimeExtension = int.Parse(item[19].ToString()),
            //        RestDay = int.Parse(item[20].ToString()),
            //        LegalHolidays = int.Parse(item[21].ToString()),
            //        TotalHours = int.Parse(item[21].ToString()),
            //    });
            //}
            #endregion
            return list;
        }

最終查詢結果如下所示:

注意事項:關聯查詢時,要考慮到查詢出來的Datarow是否為Null,因此,在給屬性賦值時,首先要判斷DataRow是否為空。

關於上述幾個考勤查詢的DataTable,可以參考本文的部落格另一篇文章。考勤查詢統計SQL