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

猜你喜欢

转载自blog.csdn.net/shenjqiang/article/details/84785187