尝试解决这个问题的好方法,最好是在Linq而不是循环中,这就是我现在所做的。
我希望我的产品在两个日期之间有效。
Product有许多ProductHistories,ProductHistory具有DateActive和DateInactive的值。 DateInactive可以为null,通常也是,以显示此历史记录正在进行中。历史不会重叠。
我想将startDate或ProductHistory的DateActive的最大值相加,并从endDate或ProductHistory的最小值DateInactive的总和中减去该总和(如果DateInactive没有值,则默认为endDate)。
工作示例:
获取2011 - 01 - 01(1月1日)和2011 - 02 - 01(2月1日)之间的有效活动天数
史:
Active 2010-12-25 : Inactive 2011-01-05
Active 2011-01-15 : Inactive 2011-01-20
Active 2011-01-25 : Inactive null
这应该总共16天(4 + 5 + 7)
我现在最擅长的是相当丑陋:
Dim a As Integer = (From h In histories
Select If(h.ActiveDate > startDate, h.ActiveDate, startDate)).Sum(Function(d) d.Ticks) / TimeSpan.TicksPerDay
Dim b As Integer = (From h In histories
Select If(h.InactiveDate.HasValue AndAlso h.InactiveDate < endDate, h.InactiveDate, endDate)).Sum(Function(d) d.Value.Ticks) / TimeSpan.TicksPerDay
Return b - a
有什么想法? (无论是C#还是VB都没问题,我会翻译)
答案 0 :(得分:1)
这样的东西? (假设没有重叠的历史)
var numDays = product
.ProductHistories
.Where(ph => ph.Active >= start && ph.Active < end)
.Sum(ph => ph.Active
.Subtract(end > ph.Inactive ? ph.Inactive.Value : end)
.Duration() // because we are doing start - end
.Days);
为了改善这一点,我建议:
IsBetween
扩展名,可以将lambda写为ph.Active.IsBetween(start, end)
。DateTime?
上使用了一个“提升”操作符,很多人会发现这种操作非常不直观。