搜索重叠的日期范围

时间:2017-12-13 14:33:51

标签: c# mongodb linq

我的产品系列包含一个日期范围列表,表示租用产品的日期。所以它看起来像这样:

"product" : {
...
 "RentalPeriods" : [
  {
   "From" : ISODate("2017-02-11T23:00:00.000Z"),
   "To" : ISODate("2017-02-12T23:00:00.000Z")
  },
  {
   "From" : ISODate("2017-10-09T23:00:00.000Z"),
   "To" : ISODate("2017-10-21T23:00:00.000Z")
  }
]
...
}

我想创建将遍历所有产品的查询,并且只返回可以在提供的日期范围内租用的产品。 所以,如果我提供类似的东西:

RentalPeriod(" 2017-03-03"," 2017-03-04") - 它应该返回上面的产品

RentalPeriod(" 2017-02-03"," 2017-02-14") - 它不应该返回上面的产品

我们尝试使用LINQ表达式,但是我们得到了不支持的过滤器异常。

所以这就是我们的尝试:

public Expression<Func<Product, bool>> IsSatisfied() =>
            product => product.RentalPeriods.All(rentPeriod => !(_fromDate > rentPeriod.FromDate && _fromDate < rentPeriod.MaybeToDate.Value) &&
                                                                !(rentPeriod.FromDate > _fromDate  && rentPeriod.FromDate < _toDate));

(以上查询是部分的,但我想我们尝试的很清楚。)

还有其他方法可以实现这一目标吗?

修改13-12-2017

public class AvailabilityForRentalPeriodSpecification : ISpecification<Product>
    {
        private UtcDate _fromDate;
        private UtcDate _toDate;

        public AvailabilityForRentalPeriodSpecification(RentalPeriod rentalPeriod)
        {
            _fromDate = rentalPeriod.FromDate;
            _toDate = rentalPeriod.MaybeToDate.Value;
        }

        public Expression<Func<Product, bool>> IsSatisfied() =>
            product => product.RentalPeriods.All(rentPeriod => !(_fromDate > rentPeriod.FromDate && _fromDate < rentPeriod.MaybeToDate.Value) &&
                                                                !(rentPeriod.FromDate > _fromDate  && rentPeriod.FromDate < _toDate));
    }

此规范在DAO层中用作:

public IList<T> GetBy(ISpecification<T> specification)
            => _mongoCollection.Find(specification.IsSatisfied()).ToList();

可能的解决方案(我试图避免)是从数据库中检索所有产品,然后在代码中过滤它们。

1 个答案:

答案 0 :(得分:0)

我更改了一个查询逻辑,使用 Any 方法而不是不支持的 All 方法,所以它现在看起来像这样:

public Expression<Func<Product, bool>> IsSatisfied() =>
            product => !product.RentalPeriods.Any(dbRentalPeriod => _fromDate >= dbRentalPeriod.FromDate && _fromDate <= dbRentalPeriod.ToDate ||
                                                                    _toDate >= dbRentalPeriod.FromDate && _toDate <= dbRentalPeriod.ToDate ||
                                                                    dbRentalPeriod.FromDate >= _fromDate && dbRentalPeriod.ToDate <= _toDate);

另一个问题是使用Maybe struct for ToDate (rentPeriod.MaybeToDate.Value),这是通过在MaybeToDate字段旁边创建内部DateTime字段来解决的。