Linq 多個DataTable表關聯查詢,實現考勤統計。
阿新 • • 發佈:2018-12-06
最近在做考勤系統時,由於不同的分公司的資料來源在不同的伺服器上,關聯查詢比較麻煩,因此想到了用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