2012-04-03 44 views
4

问题详细资料:是否可以使用linq运行查询来搜索一段时间?

  • 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做到这一点?是否有可能(忽略日期,只使用时间)?

回答

-1

- 您可以使用日期上的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); 

EDIT 2

是啊,看来你需要.ToList(),其中,tbh你应该已经能够t o弄清楚。我无法知道你有什么收藏。不知道我们当中的任何一个人值得在尝试帮助您时遇到问题

+0

在Linq查询中不能使用DateTime.Parse。 =( – 2012-04-03 14:45:56

+0

)为什么我必须输入一个日期?我不想使用日期,我的疑问是,如果可以在SQL Server 2005中不使用日期(使用EF层)进行这种比较 – 2012-04-03 14:47:18

+0

“ LINQ to Entities不支持指定的类型成员'TimeOfDay'。“ - 你在post之前测试它吗?=/ – 2012-04-03 14:54:03

-1

如果您的表中有datetime列(尽可能使用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); 
+0

@Downvoter:Care解释? – Nuffin 2012-04-03 14:43:57

+0

就像我说的,我有一个'datetime data',而不是'date'和'time'。在SQL Server 2005中不存在'time'类型,只在SQL Server 2008中。 – 2012-04-03 14:44:25

+0

你可以请尝试所提到的_alternate方法_然后(它不_要求您使用'时间列'来降低成本) – Nuffin 2012-04-03 14:48:51

3
var filteredTimes = myContext.MyTable 
    .Where(r => SqlFunctions.DatePart("hour", r.DateField) >= 11 && 
       SqlFunctions.DatePart("hour", r.DateField) <= 13); 

您需要包括System.Data.Objects.SqlClient得到SqlFunctions

+0

如果我想比较所有的时间(小时,分钟和秒),我只放秒,或有一个“TotalSeconds”? “ – 2012-04-03 16:36:15

+0

”正在使用的SQL Server版本不支持数据类型“time”。“ – 2012-04-03 16:55:23

+0

它转换为Sql [DATEPART](http://msdn.microsoft.com/en-us/library/ms174420(v = sql.90).aspx)函数,因此您可以使用任何提供给您的选项。没有总秒数,但你可以单独做每个部分。至于第二个问题,这听起来像你的edmx错了,不一定是调用SqlFunctions.DatePart – 2012-04-03 18:28:36

0

如果将日期值转换为double并使用if的小数部分,则会得到0到1之间的数字,表示一天中的某个时间。因此,测试时间间隔是微不足道的,例如, 13:45将是0,5729166667(或更确切地说:13:45.345是0,572920679)。

您可以这样做,因为EF(即4。3,我使用的版本)转换角色,甚至数学函数到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) 

其中lowerupperTimeSpan对象的TotalMilliseconds财产。

请注意,这在sql中非常低效!每个比较都重复日期函数。因此,请确保您对其他标准尽可能限制的一组数据进行比较。在内存中首先获取数据然后再进行比较可能会更好。

注:在EF6之前,DbFunctionsEntityFunctions

+0

好吧,这个我转换我在mycontext中的日期时间,以及如何我是否将作为参数的日期时间转换为双倍,以进行比较? – 2012-04-04 12:11:18

+0

对于13:45,就像'new TimeSpan(0,13,45,0,0).TotalMilliseconds/new TimeSpan(0,24,0,0,0).TotalMilliseconds'。 – 2012-04-04 12:14:01

+0

有了这个,我将返回一个IQueryble ,但是,如果我想要做这个比较并返回IQueryble ,这有可能吗? (继续在另一个参数中进行另一个比较......在这种情况下,如果这些比较是在代码的另一部分中需要的) – 2012-04-04 12:34:12

相关问题