可以使用 linq 运行查询以搜索一段时间
本文关键字:搜索 一段时间 查询 运行 linq 可以使 | 更新日期: 2023-09-27 18:29:47
问题详情:
- SQL Server 2005;
- 实体框架 4.0。
我正在尝试使用 linq 仅在一段时间内运行查询。示例:
我的服务器中有以下datetime
数据:
30/03/2012 12:53:22
30/03/2012 17:23:29
04/04/2012 11:10:14
04/04/2012 19:06:55
我想运行一个查询,该查询将返回时间(12:00 到 20:00(之间的所有数据,并且查询必须向我返回以下数据:
30/03/2012 12:53:22
30/03/2012 17:23:29
04/04/2012 19:06:55
或者在(11:00 和 13:00(之间,查询必须向我返回以下数据:
30/03/2012 12:53:22
04/04/2012 11:10:14
如何使用 linq 执行此操作?是否可以(忽略日期,仅使用时间(?
var filteredTimes = myContext.MyTable
.Where(r => SqlFunctions.DatePart("hour", r.DateField) >= 11 &&
SqlFunctions.DatePart("hour", r.DateField) <= 13);
您需要包含System.Data.Objects.SqlClient
才能获得SqlFunctions
。
如果将日期值转换为双精度值并使用 if 的小数部分,则会得到一个介于 0 和 1 之间的数字,表示一天中的某个时间。有了这个,测试时间间隔是微不足道的,例如 13:45 将是 0,5729166667(或更准确地说:13:45.345 是 0,572920679(。
您可以这样做,因为 EF(即 4.3,我使用的版本(将 Cast 甚至 Math 函数转换为 SQL:
mycontext.Data.Where(dt => dt.DateTime.HasValue)
.Select(dt => dt.DateTime.Value).Cast<double>()
.Select(d => d - Math.Floor(d))
.Where(... your comparisons
这转化为包含CAST([date column] AS float)
和 SQL FLOOR
函数的 Sql。
在您的评论之后:
看起来很容易,但我找不到一种方法来指示 EF 对Select()
中的单个属性进行CAST
。只有Cast<>()
函数被转换为CAST
(sql(,但它在一个集合上运行。
好吧,幸运的是,还有另一种方法:
mycontext.Data.Where(dt => dt.DateTime.HasValue)
.Select(dt => new
{
Date = DbFunctions.TruncateTime(dt.DateTime.Value),
Ms = DbFunctions.DiffMilliseconds(
DbFunctions.TruncateTime(dt.DateTime.Value), dt.DateTime.Value)
})
.Where(x => x.Ms > lower && x.Ms < upper)
其中lower
和upper
是TimeSpan
对象的TotalMilliseconds
属性。
请注意,这在 sql 中效率非常低!对于每个比较,都会重复日期函数。因此,请确保对一组数据进行比较,这些数据尽可能受到其他条件的限制。甚至最好先在内存中获取数据,然后再进行比较。
注意:在 EF6 之前,DbFunctions
EntityFunctions
。
如果表中有date
列和time
列(在 SQL Server 2008 中尽可能(,则可以直接在 SQL 中执行此操作。
由于情况并非如此,您必须这样做:
// the first two lines can be omitted, if your bounds are already timespans
var start = startDate.TimeOfDay;
var end = endDate.TimeOfDay;
var filteredItems = context.Items.ToList()
.Where(x => x.DateTimeColumn.TimeOfDay >= start
&& x.DateTimeColumn.TimeOfDay <= end);
- 可以使用日期上的 TimeOfDay 属性来比较它们。
string timeAsString = "13:00";
from f in TableRows
where f.Date.TimeOfDay > DateTime.Parse("11-12-2012 "+timeAsString).TimeOfDay
select f
<小时 />编辑
以下是您可以测试的一些为我运行的代码:
DateTime d = DateTime.Parse("12-12-2012 13:00");
List<DateTime> dates = new List<DateTime>();
dates.Add(DateTime.Parse("12-12-2012 13:54"));
dates.Add(DateTime.Parse("12-12-2012 12:55"));
dates.Add(DateTime.Parse("12-12-2012 11:34"));
dates.Add(DateTime.Parse("12-12-2012 14:53"));
var result = (from f in dates where f.TimeOfDay > d.TimeOfDay select f);
<小时 />编辑 2
是的,您似乎需要.ToList((,你应该能够弄清楚。我无法知道你有什么收藏。不确定我们中的任何一个是否应该在你没有提供有关该问题的大量信息时试图帮助你而投反对票