计算 Linq to Entity 组内的日期时间差和
Calculate DateTime Difference Sum within Group Linq to Entity
我有一个未返回任何内容的单元测试,我很好奇我的组或方法中的计算是否导致列表保持为 0。任何帮助或指出正确的方向将不胜感激。谢谢!
单元测试:
#region CalculateTimeToPay_IntegerEmployeeIDAndDateTimeWeekOfDate_IQueryableTimeToPay
[TestMethod]
public void CalculateTimeToPay_IntegerEmployeeIDAndDateTimeWeekOfDate_IQueryableTimeToPay()
{
//Arrange
var service = new WWIncomeTaxDataHandlerService("ProdSQL");
DateTime payrollWeekEnd = Convert.ToDateTime("2017-01-22");
DateTime payrollWeekStart = Convert.ToDateTime("2017-01-16");
var V_Times = new List<V_Time>()
{
new V_Time { PayTimeIn = Convert.ToDateTime("2017-01-05 08:00:00.000"), PayTimeOut = Convert.ToDateTime("2017-01-05 16:00:00.000"), EmployeeID = 999 },
new V_Time { PayTimeIn = Convert.ToDateTime("2017-01-05 08:30:00.000"), PayTimeOut = Convert.ToDateTime("2017-01-05 16:00:00.000"), EmployeeID = 777 },
new V_Time { PayTimeIn = Convert.ToDateTime("2017-01-05 08:45:00.000"), PayTimeOut = Convert.ToDateTime("2017-01-05 16:00:00.000"), EmployeeID = 888 },
new V_Time { PayTimeIn = Convert.ToDateTime("2017-01-10 08:00:00.000"), PayTimeOut = Convert.ToDateTime("2017-01-10 16:00:00.000"), EmployeeID = 999 },
new V_Time { PayTimeIn = Convert.ToDateTime("2017-01-10 08:30:00.000"), PayTimeOut = Convert.ToDateTime("2017-01-10 16:00:00.000"), EmployeeID = 777 },
new V_Time { PayTimeIn = Convert.ToDateTime("2017-01-10 08:45:00.000"), PayTimeOut = Convert.ToDateTime("2017-01-10 16:00:00.000"), EmployeeID = 888 },
new V_Time { PayTimeIn = Convert.ToDateTime("2017-01-11 08:00:00.000"), PayTimeOut = Convert.ToDateTime("2017-01-11 16:00:00.000"), EmployeeID = 999 },
new V_Time { PayTimeIn = Convert.ToDateTime("2017-01-11 00:00:00.000"), PayTimeOut = Convert.ToDateTime("2017-01-11 07:00:00.000"), EmployeeID = 777 },
new V_Time { PayTimeIn = Convert.ToDateTime("2017-01-11 08:00:00.000"), PayTimeOut = Convert.ToDateTime("2017-01-11 16:00:00.000"), EmployeeID = 888 },
new V_Time { PayTimeIn = Convert.ToDateTime("2017-01-12 08:00:00.000"), PayTimeOut = Convert.ToDateTime("2017-01-12 16:00:00.000"), EmployeeID = 999 },
new V_Time { PayTimeIn = Convert.ToDateTime("2017-01-12 08:00:00.000"), PayTimeOut = Convert.ToDateTime("2017-01-12 16:44:00.000"), EmployeeID = 777 },
new V_Time { PayTimeIn = Convert.ToDateTime("2017-01-12 08:00:00.000"), PayTimeOut = Convert.ToDateTime("2017-01-12 16:00:00.000"), EmployeeID = 888 },
new V_Time { PayTimeIn = Convert.ToDateTime("2017-01-14 08:00:00.000"), PayTimeOut = Convert.ToDateTime("2017-01-14 16:07:00.000"), EmployeeID = 777 }
};
var mockRepository = new Mock<IRepository>();
mockRepository.Setup(x => x.Find<V_Time>()).Returns(V_Times.AsQueryable());
var builder = BuildContainer();
builder.Register(x => mockRepository.Object).As<IRepository>();
var container = builder.Build();
var itrs = container.Resolve<WWIncomeTaxDataHandler.Domain.WWIncomeTaxDataHandlerService>();
var expected = new List<calculatedHours>()
{
new calculatedHours { EmployeeID = 999, TimeToPay = 24 },
new calculatedHours { EmployeeID = 888, TimeToPay = 31.35},
new calculatedHours { EmployeeID = 777, TimeToPay = 23.25}
};
//Act
var actual = itrs.CalculateTimeToPay(payrollWeekStart, payrollWeekEnd);
//Assert
var compareLogic = new CompareLogic();
var result = compareLogic.Compare(actual, expected);
Assert.IsTrue(result.AreEqual, result.DifferencesString);
}
#endregion
方法:
#region CalculateTimeToPay(payrollWeekEnd)
public IQueryable CalculateTimeToPay(DateTime payrollWeekStart, DateTime payrollWeekEnd)
{
var uow = container.Resolve<WWIncomeTaxDataHandlerUnitOfWork>();
var employeeHours = (from time in uow.Accounting.Repository.Find<V_Time>()
where (payrollWeekEnd >= time.PayTimeIn && time.PayTimeIn >= payrollWeekStart)
group time by new { time.EmployeeID } into empGroup
select new calculatedHours
{
EmployeeID = empGroup.Key.EmployeeID,
TimeToPay = empGroup.Where(x => x.EmployeeID == empGroup.Key.EmployeeID).Sum (x => ((x.PayTimeOut - x.PayTimeIn).TotalSeconds) / 60 / 60)
}).ToList();
return employeeHours.AsQueryable();
}
#endregion
注意 tolist 和返回可查询是为了更快的测试
你正在用一堆匿名数据类型做这件事非常复杂。您可以尝试更多 C# 风格:
public class CalculatedHours
{
public int EmployeeId { get; set; }
public TimeSpan TimeToPay { get; set; }
}
public class PayTime
{
public DateTime PayTimeIn { get; set; }
public DateTime PayTimeOut { get; set; }
public int EmployeeId { get; set; }
public TimeSpan CalculateTimeToPay(DateTime payrollWeekStart, DateTime payrollWeekEnd)
{
DateTime realIn = payrollWeekStart > this.PayTimeIn ? payrollWeekStart : this.PayTimeIn;
DateTime realOut = payrollWeekEnd < this.PayTimeOut ? payrollWeekEnd : this.PayTimeOut;
return realOut - realIn;
}
public static void Test()
{
List<PayTime> someData = new List<PayTime>() { };
DateTime payrollWeekEnd = Convert.ToDateTime("2017-01-22");
DateTime payrollWeekStart = Convert.ToDateTime("2017-01-16");
IEnumerable<CalculatedHours> result = someData.GroupBy(g => g.EmployeeId)
.Select(s => new CalculatedHours() { EmployeeId = s.Key, TimeToPay = new TimeSpan(s.Sum(a => a.CalculateTimeToPay(payrollWeekStart, payrollWeekEnd).Ticks)) });
// Do some assertions
}
}
顺便说一句。你的测试数据是错误的。 payrollWeekStart
和 payrollWeekEnd
为时已晚(2017-01-16 至 2017-01-22 数据最大为 2017-01-14)。
另外你不计算兼职工资..
我有一个未返回任何内容的单元测试,我很好奇我的组或方法中的计算是否导致列表保持为 0。任何帮助或指出正确的方向将不胜感激。谢谢!
单元测试:
#region CalculateTimeToPay_IntegerEmployeeIDAndDateTimeWeekOfDate_IQueryableTimeToPay
[TestMethod]
public void CalculateTimeToPay_IntegerEmployeeIDAndDateTimeWeekOfDate_IQueryableTimeToPay()
{
//Arrange
var service = new WWIncomeTaxDataHandlerService("ProdSQL");
DateTime payrollWeekEnd = Convert.ToDateTime("2017-01-22");
DateTime payrollWeekStart = Convert.ToDateTime("2017-01-16");
var V_Times = new List<V_Time>()
{
new V_Time { PayTimeIn = Convert.ToDateTime("2017-01-05 08:00:00.000"), PayTimeOut = Convert.ToDateTime("2017-01-05 16:00:00.000"), EmployeeID = 999 },
new V_Time { PayTimeIn = Convert.ToDateTime("2017-01-05 08:30:00.000"), PayTimeOut = Convert.ToDateTime("2017-01-05 16:00:00.000"), EmployeeID = 777 },
new V_Time { PayTimeIn = Convert.ToDateTime("2017-01-05 08:45:00.000"), PayTimeOut = Convert.ToDateTime("2017-01-05 16:00:00.000"), EmployeeID = 888 },
new V_Time { PayTimeIn = Convert.ToDateTime("2017-01-10 08:00:00.000"), PayTimeOut = Convert.ToDateTime("2017-01-10 16:00:00.000"), EmployeeID = 999 },
new V_Time { PayTimeIn = Convert.ToDateTime("2017-01-10 08:30:00.000"), PayTimeOut = Convert.ToDateTime("2017-01-10 16:00:00.000"), EmployeeID = 777 },
new V_Time { PayTimeIn = Convert.ToDateTime("2017-01-10 08:45:00.000"), PayTimeOut = Convert.ToDateTime("2017-01-10 16:00:00.000"), EmployeeID = 888 },
new V_Time { PayTimeIn = Convert.ToDateTime("2017-01-11 08:00:00.000"), PayTimeOut = Convert.ToDateTime("2017-01-11 16:00:00.000"), EmployeeID = 999 },
new V_Time { PayTimeIn = Convert.ToDateTime("2017-01-11 00:00:00.000"), PayTimeOut = Convert.ToDateTime("2017-01-11 07:00:00.000"), EmployeeID = 777 },
new V_Time { PayTimeIn = Convert.ToDateTime("2017-01-11 08:00:00.000"), PayTimeOut = Convert.ToDateTime("2017-01-11 16:00:00.000"), EmployeeID = 888 },
new V_Time { PayTimeIn = Convert.ToDateTime("2017-01-12 08:00:00.000"), PayTimeOut = Convert.ToDateTime("2017-01-12 16:00:00.000"), EmployeeID = 999 },
new V_Time { PayTimeIn = Convert.ToDateTime("2017-01-12 08:00:00.000"), PayTimeOut = Convert.ToDateTime("2017-01-12 16:44:00.000"), EmployeeID = 777 },
new V_Time { PayTimeIn = Convert.ToDateTime("2017-01-12 08:00:00.000"), PayTimeOut = Convert.ToDateTime("2017-01-12 16:00:00.000"), EmployeeID = 888 },
new V_Time { PayTimeIn = Convert.ToDateTime("2017-01-14 08:00:00.000"), PayTimeOut = Convert.ToDateTime("2017-01-14 16:07:00.000"), EmployeeID = 777 }
};
var mockRepository = new Mock<IRepository>();
mockRepository.Setup(x => x.Find<V_Time>()).Returns(V_Times.AsQueryable());
var builder = BuildContainer();
builder.Register(x => mockRepository.Object).As<IRepository>();
var container = builder.Build();
var itrs = container.Resolve<WWIncomeTaxDataHandler.Domain.WWIncomeTaxDataHandlerService>();
var expected = new List<calculatedHours>()
{
new calculatedHours { EmployeeID = 999, TimeToPay = 24 },
new calculatedHours { EmployeeID = 888, TimeToPay = 31.35},
new calculatedHours { EmployeeID = 777, TimeToPay = 23.25}
};
//Act
var actual = itrs.CalculateTimeToPay(payrollWeekStart, payrollWeekEnd);
//Assert
var compareLogic = new CompareLogic();
var result = compareLogic.Compare(actual, expected);
Assert.IsTrue(result.AreEqual, result.DifferencesString);
}
#endregion
方法:
#region CalculateTimeToPay(payrollWeekEnd)
public IQueryable CalculateTimeToPay(DateTime payrollWeekStart, DateTime payrollWeekEnd)
{
var uow = container.Resolve<WWIncomeTaxDataHandlerUnitOfWork>();
var employeeHours = (from time in uow.Accounting.Repository.Find<V_Time>()
where (payrollWeekEnd >= time.PayTimeIn && time.PayTimeIn >= payrollWeekStart)
group time by new { time.EmployeeID } into empGroup
select new calculatedHours
{
EmployeeID = empGroup.Key.EmployeeID,
TimeToPay = empGroup.Where(x => x.EmployeeID == empGroup.Key.EmployeeID).Sum (x => ((x.PayTimeOut - x.PayTimeIn).TotalSeconds) / 60 / 60)
}).ToList();
return employeeHours.AsQueryable();
}
#endregion
注意 tolist 和返回可查询是为了更快的测试
你正在用一堆匿名数据类型做这件事非常复杂。您可以尝试更多 C# 风格:
public class CalculatedHours
{
public int EmployeeId { get; set; }
public TimeSpan TimeToPay { get; set; }
}
public class PayTime
{
public DateTime PayTimeIn { get; set; }
public DateTime PayTimeOut { get; set; }
public int EmployeeId { get; set; }
public TimeSpan CalculateTimeToPay(DateTime payrollWeekStart, DateTime payrollWeekEnd)
{
DateTime realIn = payrollWeekStart > this.PayTimeIn ? payrollWeekStart : this.PayTimeIn;
DateTime realOut = payrollWeekEnd < this.PayTimeOut ? payrollWeekEnd : this.PayTimeOut;
return realOut - realIn;
}
public static void Test()
{
List<PayTime> someData = new List<PayTime>() { };
DateTime payrollWeekEnd = Convert.ToDateTime("2017-01-22");
DateTime payrollWeekStart = Convert.ToDateTime("2017-01-16");
IEnumerable<CalculatedHours> result = someData.GroupBy(g => g.EmployeeId)
.Select(s => new CalculatedHours() { EmployeeId = s.Key, TimeToPay = new TimeSpan(s.Sum(a => a.CalculateTimeToPay(payrollWeekStart, payrollWeekEnd).Ticks)) });
// Do some assertions
}
}
顺便说一句。你的测试数据是错误的。 payrollWeekStart
和 payrollWeekEnd
为时已晚(2017-01-16 至 2017-01-22 数据最大为 2017-01-14)。
另外你不计算兼职工资..