简体   繁体   English

搜索重叠的日期范围

[英]Search for overlapping date ranges

I have product collection with a list of date ranges that represent dates when products are rented. 我有一个带有日期范围列表的产品集合,这些日期范围表示产品租用的日期。 So it looks something like this: 所以看起来像这样:

"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")
  }
]
...
}

I want to create query that will go through all products and to return only products that can be rented for provided date range. 我想创建查询所有产品的查询,并只返回在指定日期范围内可以租用的产品。 So if I provide something like: 因此,如果我提供以下信息:

RentalPeriod("2017-03-03", "2017-03-04") - it should return above product RentalPeriod(“ 2017-03-03”,“ 2017-03-04”)-应该返回以上产品

RentalPeriod("2017-02-03", "2017-02-14") - it should not return above product RentalPeriod(“ 2017-02-03”,“ 2017-02-14”)-它不应返回以上产品

We tried with LINQ expression, but we got Unsupported filter Exception. 我们尝试使用LINQ表达式,但是得到了不支持的过滤器异常。

So this is what we tried: 所以这是我们尝试的:

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

(Above query is partial, but I suppose it is clear what we tried). (以上查询是局部的,但我想很清楚我们尝试了什么)。

Is there any other way how we can achieve this? 还有其他方法可以实现这一目标吗?

Edit 13-12-2017 : 编辑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));
    }

This specification is used in DAO layer as: 该规范在DAO层中用作:

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

Possible solution (that I'm trying to avoid) is to retrieve all products from DB and then to filter them in the code. 可能的解决方案(我试图避免)是从DB中检索所有产品,然后在代码中对其进行过滤。

I changed a query logic to use Any method instead of unsupported All method, so it looks like this now: 我将查询逻辑更改为使用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);

Another problem was using Maybe struct for ToDate (rentPeriod.MaybeToDate.Value), which is resolved by creating internal DateTime field next to the MaybeToDate field. 另一个问题是对ToDate使用了Maybe结构(rentPeriod.MaybeToDate.Value),可以通过在MaybeToDate字段旁边创建内部DateTime字段来解决。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM