任何人都可以将此SQL查询转换为C#Linq语句吗?

时间:2016-03-07 16:17:17

标签: c# sql linq

我有一个SQL查询,如下所示:

SELECT [ClientId]
  ,[LastDelivery]
  ,[LastRequisitionDate]
  ,Datediff (day, LastRequisitionDate, LastDelivery) as DiffDate
  FROM [dbo].[App_Client]
  where  (LastDelivery != '1900-01-01 00:00:00' 
  and LastRequisitionDate != '1900-01-01 00:00:00') 
  and Inactive = 0
  and (Datediff (day, LastRequisitionDate, LastDelivery) < 9)
  and (Datediff (day, LastRequisitionDate, LastDelivery) >= 0)

我有一份客户名单,我希望所有在收到请求后8天内收到货的客户。

的原因
LastDelivery != '1900-01-01 00:00:00' 
and LastRequisitionDate != '1900-01-01 00:00:00'

是因为我拥有c#查询的方式要求任何日期字段中都没有空字段(这些字段在数据库中可以为空,但实际上不应该是这样)。我有一个包含11838个客户端的数据库,此查询返回10404.我的问题是我无法用C#linq复制此查询。

我的C#查询如下:

var clients = _clientService.GetAllClients().Where(x => 
(x.LastDelivery != Convert.ToDateTime("01/01/1900")
&& x.LastRequisitionDate != Convert.ToDateTime("01/01/1900"))
&& x.Inactive == 0
&& (((DateTime)x.LastDelivery - (DateTime)x.LastRequisitionDate).Days < 9)
&& (((DateTime)x.LastDelivery - (DateTime)x.LastRequisitionDate).Days >= 0)).ToList();

这个查询返回10563个结果,差值为159,我无法弄明白我出错的地方。对我来说,C#查询看起来与SQL相同,但某处存在差异。我整天都在编码,所以也许我有点烦,解决方案很明显,但我看不出来。任何人都可以提供帮助,或建议我可能做错了什么或忽略了什么?

答案

正如Matt Smith在下面正确指出的那样,事实证明两个查询都是正确的 - 这个差异存在于SQL DateDiff函数中,该函数测量当天午夜过去的1天,这意味着比较01/01/2016 23:59 :59和01/02/2016 00:00:01给出了一天的差异,而在我的C#查询中,它将实际的天数差异作为时间跨度(24小时)进行比较。很好的发现和重要的区别,感谢马特史密斯。

3 个答案:

答案 0 :(得分:2)

由于我没有您的数据,我无法确定这是否有效,但请谨慎使用。至少应该给你一些东西

    var clients = (from client in _clientService.GetAllClients()
                    let minDate = DateTime.MinValue
                    let lastRequisitionDate = (DateTime)client.LastRequisitionDate
                    let lastDeliveryDate = (DateTime)client.LastDeliveryDate
                    let lastDelivery = (DateTime)client.LastDelivery
                    where lastRequisitionDate != minDate && lastDelivery != minDate && client.Inactive != 0 && (lastDelivery - lastRequisitionDate).Days < 9 && (lastDelivery - lastRequisitionDate).Days >= 0
                    select client).ToList();

通过更改Client实体以允许可以为空的日期,您还可以让自己更轻松:

public class Client
{
    public DateTime? LastRequisitionDate {get; set;}
}

答案 1 :(得分:2)

您的日期值中是否包含时间组件?如果是这样,DateDiff在SQL中的工作方式之间存在重要差异,其中DateDiff(日,&03; 03/06/2016 23:59:59&#39;,&#39; 03/07/2016 00:00 :01&#39;)= 1,和.NET在哪里(&#39; 03/07/2016 23:00:00&#39; - &#39; 03/06/2016 23:59:00&#39;) .Days = 0. DateDiff(day,x,y)测量越过的Day边界数。在.NET中,DateTimes的减法返回TimeSpan的天,小时,分钟,秒,毫秒,TimeSpan.Days返回TimeSpan中的天数。

答案 2 :(得分:1)

    var clients = (from a in _clientService.GetAllClients().ToList()
               where
               (a.LastDelivery != DateTime.Parse("1900-01-01 00:00:00")
               &&
               a.LastRequisitionDate != DateTime.Parse("1900-01-01 00:00:00"))
               && ((a.LastRequisitionDate - a.LastDelivery).Days < 9)
               && ((a.LastRequisitionDate - a.LastDelivery).Days >= 0)
               && a.Inactive == 0
               select a).ToList();