【问题标题】:Search for overlapping date ranges搜索重叠的日期范围
【发布时间】:2017-12-14 18:18:44
【问题描述】:

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

"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));

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

还有其他方法可以实现吗?

2017 年 13 月 12 日编辑

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();

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

【问题讨论】:

  • 请说明您如何在 LINQ 查询中使用 IsSatisfied 表达式,以及表达式 _fromDate_toDate 的声明位置。
  • @GertArnold 我更新了问题
  • 你甚至可以在 mongoDb LINQ 提供程序中使用“”和 DateTime 吗?尝试使用一个普通的 lambda 表达式来执行查询。

标签: c# mongodb linq


【解决方案1】:

我将查询逻辑更改为使用 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);

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-18
    • 1970-01-01
    • 2018-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多