1

当用户超时的第二天超过生物识别读数时,我在获取结构化的第一个条目和最后一个条目时遇到问题。但是,如果进出时间是在同一天,我可以按照我想要的方式对其进行格式化..

这是我的代码:

     IEnumerable<biometric> dtrs = new List<biometric>()
        {
            new biometric{Id = 1, InOut = 0, DateTime = new DateTime(2013,5,5,8,0,0)},
            new biometric{Id = 2, InOut = 0, DateTime = new DateTime(2013,5,5,8,0,5)},
            new biometric{Id = 3, InOut = 0, DateTime = new DateTime(2013,5,5,8,1,0)},
            new biometric{Id = 4, InOut = 0, DateTime = new DateTime(2013,5,5,8,2,0)},

           //here is my problem getting this paired to
            new biometric{Id = 5, InOut = 0, DateTime = new DateTime(2013,5,5,18,0,0)},

            new biometric{Id = 1, InOut = 1, DateTime = new DateTime(2013,5,5,18,0,0)},
            new biometric{Id = 2, InOut = 1, DateTime = new DateTime(2013,5,5,17,5,5)},
            new biometric{Id = 3, InOut = 1, DateTime = new DateTime(2013,5,5,17,5,10)},
            new biometric{Id = 4, InOut = 1, DateTime = new DateTime(2013,5,5,17,10,0)},

            //this Entry here
            new biometric{Id = 5, InOut = 1, DateTime = new DateTime(2013,5,6,3,0,0)},
        };

        var asd = dtrs.GroupBy(x => new { x.Id, x.DateTime.Date }, (key, group) => new
        {
            Key1 = key.Date,
            Key2 = key.Id,
            Result = group.OrderBy(a => a.DateTime).ToList()
        })
         //checks if the grouping result has one timein and 1 timeout or more
        .Where(a => a.Result.Where(z => z.InOut == 1).Count() >= 1 && a.Result.Where(z => z.InOut == 0).Count() >= 1)
        .Select(a => new dtr() { employeeId = a.Key2, TimeIn = a.Result.FirstOrDefault(b => b.InOut == 1).DateTime, TimeOut = a.Result.LastOrDefault(c => c.InOut == 0).DateTime });



     private class biometric
      {
        public int Id { get; set; }
        public DateTime DateTime { get; set; }
        public int InOut { get; set; }
      }

      private class dtr
      {
        public int employeeId { get; set; }
        public DateTime TimeIn { get; set; }
        public DateTime TimeOut { get; set; }
       }

我想配对这个
新的生物识别{Id = 5, InOut = 0, DateTime = new DateTime(2013,5,5,18,0,0)},

到这个
新的生物特征{Id = 5, InOut = 1, DateTime = new DateTime(2013,5,6,3,0,0)},

任何解决方法或建议?

4

1 回答 1

1
    var asd3 =  from d1 in dtrs
                join d2 in dtrs on d1.Id equals d2.Id
                where d1.InOut ==0 
                   && d2.InOut == 1 
                   && d2.DateTime > d1.DateTime 
                   && d2.DateTime.AddHours(-18) < d1.DateTime 
                orderby d1.DateTime.Date, d1.Id
                select new dtr {employeeId = d1.Id,
                                TimeIn=d1.DateTime,
                                TimeOut= d2.DateTime};

我添加了第二天的数据,以确保过滤是正确的。这假设没有人一天工作超过 18 小时。假设大多数人的标准工作时间为 8 小时,则可以将其设置为 31 小时。

employeeId TimeIn                         TimeOut
1         05/05/2013 08:00:00.000         05/05/2013 18:00:00.000 
2         05/05/2013 08:00:05.000         05/05/2013 17:05:05.000 
3         05/05/2013 08:01:00.000         05/05/2013 17:05:10.000 
4         05/05/2013 08:02:00.000         05/05/2013 17:10:00.000 
5         05/05/2013 18:00:00.000         05/06/2013 03:00:00.000 
1         05/06/2013 08:00:00.000         05/06/2013 18:00:00.000 
2         05/06/2013 08:00:05.000         05/06/2013 17:05:05.000 
3         05/06/2013 08:01:00.000         05/06/2013 17:05:10.000 
4         05/06/2013 08:02:00.000         05/06/2013 17:10:00.000 
5         05/06/2013 18:00:00.000         05/07/2013 03:00:00.000 

另外,作为旁注,您的原始代码包含a.Result.Where(z => z.InOut == 1).Count() >= 1. 这可以减少到a.Result.Any(z => z.InOut == 1),除了简洁和易于阅读之外,执行速度可能会更快。

更新:添加这两条记录(员工 1 去吃午饭)

        new biometric{Id = 1, InOut = 1, DateTime = new DateTime(2013,5,5,12,0,0)},
        new biometric{Id = 1, InOut = 0, DateTime = new DateTime(2013,5,5,13,0,1)},


var sorted = dtrs.OrderBy (d =>d.Id).ThenBy (d =>d.DateTime ).ToList();

var zipped = sorted.Where (d =>d.InOut==0 ).Zip(sorted.Where (s =>s.InOut==1),
                (i,o)=>{
                        Debug.Assert(i.Id == o.Id);
                        return new dtr
                    {
                        employeeId = i.Id, 
                        TimeIn=i.DateTime,
                        TimeOut= o.DateTime
                    };
                }).OrderBy (d =>d.TimeIn);
zipped.Dump();
于 2016-07-26T21:58:21.183 回答