2012-02-03 71 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并比较那些(作为整数)。