如何在 Linq to SQL 中给日期加上天数

20

我正在编写这段代码。这里的dt是作为函数的输入参数,一些整数也是如此。列Exp是一个T-SQL日期列,通过Linq以DateTime形式返回。

return (from a in dataContext.TableOfA
       where a.name == "Test" &&
       a.Exp.Value.AddDays(Convert.ToDouble(Someint)) >= new DateTimeOffset(dt)
       select a).First();
在C#中,你可以将一个浮点数作为天数添加到日期时间中。也就是说,你可以加上1.5天。但在T-SQL中,你只能加上1天和12小时,并且必须为每个部分都添加一个整数。因此,当Linq将AddDays转换为T-SQL时,它会将我的天数转换为毫秒,并添加这些毫秒。这使得它能够给出与C#中双精度浮点数相同的精度。
问题在于当这个值传递到SQL时,会出现如下错误信息:
“数据类型为date的dateadd函数不支持单位毫秒。”
基本上你不能向日期添加毫秒。那么我该如何解决这个问题呢?我想要向日期添加整数天数。难道唯一的方法就是向需要比较的另一个日期添加这些天数的负值吗?如果我想同时向两个列添加这些天数,该怎么办?
更新1:
Keith写道,“自从SQL Server 2000以来,T-SQL已经支持了类似datepart(毫秒,10000,myDate)这样的命令。这个错误表明你使用的任何数据库都不支持毫秒日期部分,这对我来说似乎很奇怪。”
请注意,我正在使用SQL Server 2008。它不支持DATE数据类型上的毫秒,但支持datetime。

自 SQL Server 2000 起,T-SQL 支持像 datepart(millisecond, 10000, myDate) 这样的命令。这个错误表明您正在使用的数据库不支持毫秒日期部分,这对我来说似乎很奇怪。 - Keith
不支持 DATE 数据类型,但支持 datetime。 - Anthony D
这样更有意义。如果您对数据库设计有控制权,那么简单的解决方案就是将此列从DATE更改为DATETIME。显然,如果您正在问这个问题,那么您无法控制这个? - Keith
10个回答

10

如果你正在使用Entity Framework,请按以下方式使用System.Data.Objects.EntityFunctions:

c.CMT_TS > System.Data.Objects.EntityFunctions.AddDays(e.Call.CALL_TS, 1)

4
2019年,EntityFunctions已被弃用,请使用System.Data.Entity.DbFunctions代替。 - AlexB

5

我刚刚将该列更改为DateTime类型。


4
创建一个新的DateTime对象,然后使用AddDays方法:
new DateTime(t.Key.Year,t.Key.Month,T.Key.Day).AddDays(xx)

4
你可以使用:System.Data.Entity.DbFunctions.AddDays(YourDateTime, NumberOfDays) 这个函数会被转换为有效的SQL查询语句。类System.Data.Entity.Core.Objects.EntityFunctions中也包含AddDays函数,但已经过时。

3

看起来这种情况在.NET 4.5中大多已经得到了解决。

然而,如果你写下如下代码:

var activeProducts = from p in db.Products where DateTime.Now() <= p.EndDate.Date.AddDays(7) select p;

你会得到与OP描述相同的错误消息。
但是,如果你写成:
var activeProducts = from p in db.Products where DateTime.Now() <= p.EndDate.AddDays(7) select p;

然后您就可以进入牛奶和蜂蜜之地了。请注意,我没有在数据库的DateTime表示上调用.Date。这似乎是一个边缘情况,被LINQ 2 SQL framework在4.5中缺少测试覆盖。


6
我正在使用.NET 4.5.1,而你给我的两种情况都出现了“不受LINQ支持”的错误。 - mgrenier
它说在这里得到支持,所以我需要更多信息:https://msdn.microsoft.com/zh-cn/library/bb882657(v=vs.100).aspx - John Zabroski

3
您可以将对 AddDays 的调用从 SQL 部分移到 .NET 部分:
a.Exp.Value >= new DateTimeOffset(dt).AddDays(-Convert.ToDouble(Someint))

2

1

我用那个查询解决了我的问题。

return (from a in dataContext.TableOfA
       where a.name == "Test" &&
       DbFunctions.AddHours(DbFunctions.CreateDateTime(
 a.Exp.Value.Year,a.Exp.Value.Month,a.Exp.Value.Day,a.Exp.Value.Hour,a.Exp.Value.Minute,
a.Exp.Value.Millisecond),Someint) >=     
DbFunctions.CreateDateTimeOffset(dt.Year,dt.Month,dt.Day,dt.Hour,dt.Minute,dt.Millisecond,0)
       select a).First();

0
你有没有考虑编写自己的用户定义函数,基本上接受一个整数(表示天数)和日期,返回dateadd()的结果?然后将其拉入项目中的LINQ类。然后,不要调用.AddDate(),而是调用你的UDF - 这将允许你在LINQ查询中保持一切,而无需手动拼凑SQLCommand。

-2

如果你先将SQL查询更改为Linq并处理Linq查询,可能是个不错的主意。

只需添加ToList()或限制记录即可。

return (from a in dataContext.TableOfA.ToList()
   where a.name == "Test" &&
   a.Exp.Value.AddDays(Convert.ToDouble(Someint)) >= new DateTimeOffset(dt)
   select a).First();

所以一旦你把所有的东西都放在 Linq 中,我认为你就可以更有效地处理了。

干杯


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接