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

时间:2013-10-25 15:26:56

标签: c# linq linq-to-sql linq-to-entities

我有一个DateRange对象列表,它们具有StartDate和EndDate属性。我需要从数据库中的表中选择所有行,这些行的DateTime字段属于任何DateRanges。所以我想做这样的事情:

// 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不能使用它。有没有其他方法可以做我想在这里做的事情?谷歌搜索和尝试不同的东西几个小时,我觉得我非常接近,但不能完全到达那里。提前谢谢。

3 个答案:

答案 0 :(得分:0)

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

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

示例:Linq2SQL "or/and" operators (ANDed / ORed conditions)

答案 1 :(得分:0)

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

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

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

答案 2 :(得分:-1)

通过连接每个范围的条件来制作自己的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));

这对于一个范围是完美的,除非你的范围之间存在巨大的差距,否则只会略微恶化。