2012-04-03 60 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

相關問題