Linq to SQL 以选择其 DateTime 字段位于任何日期范围列表中的行

本文关键字:范围 日期 于任何 列表 字段 SQL to 选择 DateTime Linq | 更新日期: 2023-09-27 18:37:02

我有一个日期范围对象列表,这些对象具有StartDate和EndDate属性。 我需要从数据库中的表中选择具有属于任何这些日期范围中的任何日期时间字段的所有行。 所以我想做这样的事情:

// Using an IQueryable<DateRange> called dateRanges
var tests = from test in dbContext.Tests
            where dateRanges.Any(range => range.StartDate <= test.Date && range.EndDate >= test.Date)
            select test

这给了我一个错误,因为 DateRange 不是基元类型,因此 LINQ to SQL 无法使用它。 还有其他方法可以做我在这里想做的事情吗? 几个小时一直在谷歌搜索和尝试不同的东西,我觉得我非常接近,但无法完全到达那里。 提前谢谢。

Linq to SQL 以选择其 DateTime 字段位于任何日期范围列表中的行

尝试将 Linq2Sql 与动态查询一起使用,例如

(p => value1.StartDate <= p.Date && value1.EndDate >= p.Date) || (p => value2.StartDate <= p.Date && value2.EndDate >= p.Date)

示例:Linq2SQL "or/and" 运算符(ANDed/ORed 条件)

为了保证不会传输不必要的数据,我决定这样做的方法是在我的数据库上创建一个名为 GetTestsInDateRange 的存储过程,该过程接受开始和结束日期并返回该范围内的所有测试。 然后,在我的代码中,我循环访问我的日期范围列表,为每个日期范围调用一次存储过程,并将结果合并在一起。

IEnumerable<Test> tests = new List<Test>();
foreach (DateRange range in selectedDateRanges)
{
    tests = tests.Union(dbContext.GetTestsInDateRange(range.StartDate, range.EndDate));
}

我不知道这是否是理想的解决方案(可能取决于选择了多少个 DateRanges,因此它对数据库进行了多少次单独调用),但它适用于我的方案。

除了通过连接每个范围的条件来制作自己的 SQL 语句之外,部分限制返回结果的一种方法是使用范围的最小和最大日期,然后在 Linq-To-Objects 中进一步过滤:

var minStartDate = dateRanges.Min(r => r.StartDate);
var maxEndDate = dateRanges.Max(r => r.EndDate);
var tests = (from test in dbContext.Tests
            where minStartDate <= test.Date && maxEndDate >= test.Date
            select test)
            .AsEnumerable()  // change to Linq-To-Objects
            .Where(test => dateRanges.Any(range => range.StartDate <= test.Date 
                                                   && range.EndDate >= test.Date));

这将完美地适用于一个范围,并且只会稍微差一点,除非您的范围之间有巨大的差距。