2012-02-03 70 views
0

我想從表中選擇記錄基於日期使用Linq to SQL。不幸的是,日期分成兩個表 - 小時表有一天,相關的工作時間表有兩列中的月份和年份。LINQ to SQL選擇記錄並轉換日期

我有以下查詢:

Dim qry = From h As Hour In ctx.Hours Where Convert.ToDateTime(h.day & "/" & h.JobTime.month & "/" & h.JobTime.year & " 00:00:00") > Convert.ToDateTime("01/01/2012 00:00:00") 

這給我的錯誤「算術溢出錯誤將表達式轉換爲數據類型日期時間。」

望着SQL Server Profiler中的SQL查詢,我看到:

exec sp_executesql N'SELECT [t0].[JobTimeID], [t0].[day], [t0].[hours] 
FROM [dbo].[tbl_pm_hours] AS [t0] 
INNER JOIN [dbo].[tbl_pm_jobtimes] AS [t1] ON [t1].[JobTimeID] = [t0].[JobTimeID] 
WHERE (CONVERT(DateTime,(((((CONVERT(NVarChar,[t0].[day])) + @p0) + (CONVERT(NVarChar,COALESCE([t1].[month],NULL)))) + @p1) + (CONVERT(NVarChar,COALESCE([t1].[year],NULL)))) + @p2)) > @p3',N'@p0 nvarchar(4000),@p1 nvarchar(4000),@p2 nvarchar(4000),@p3 datetime',@p0=N'/',@p1=N'/',@p2=N' 00:00:00',@p3='2012-01-31 00:00:00' 

我可以看到,它不是在日期傳球尋找正確的,但我不知道如何糾正它。

任何人都可以請幫忙嗎?

感謝, 艾瑪

回答

0

錯誤的直接原因可能與this issue做。

如上所述,您使用的轉換是構建查詢的非常低效的方式。最重要的是,效率不高,因爲表達式不是sargable。即您在比較中使用了數據庫列中的計算值,該比較禁止查詢分析器使用索引跳轉到單個列值。所以,你可以嘗試通過修正直接原因來修復錯誤,但我認爲最好是重寫查詢,以便在比較中只使用單列值。

我在C#中工作了這一點:

var cfg = new DateTime(12,6,12); 
int year = 12, month = 6, day = 13; // Try some more values here. 

// Date from components > datetime value? 
bool gt = (
    year > cfg.Year || (
     (year == cfg.Year && month > cfg.Month) || (
      year == cfg.Year && month == cfg.Month && day > cfg.Day) 
    ) 
); 

你看,它不是那麼簡單,因爲它可能看起來在第一,但它的工作原理。有更多的比較工作,但我相信使用索引的能力將輕易超過這個。

更簡單但不可靠的方法是使用排序日期,比如20120101並比較那些(作爲整數)。