简体   繁体   English

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

[英]Can anyone convert this SQL query into a C# Linq statement?

I have a SQL query which is as follows: 我有一个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)

I have a list of clients, and I want all clients who received their delivery within 8 days of their requisition. 我有一个客户清单,我希望所有在申请后8天内收到交货的客户。 The reason for the 的原因

LastDelivery != '1900-01-01 00:00:00' 
and LastRequisitionDate != '1900-01-01 00:00:00'

is because the way I have my c# query requires that there are no null fields in any of the date fields(those fields are nullable in the DB but they really shouldn't be). 是因为我进行c#查询的方式要求在任何日期字段中都没有null字段(这些字段在数据库中是可为null的,但实际上不应该为null)。 I have a DB containing 11838 clients, and this query returns 10404. My problem is I have been unable to duplicate this query with C# linq. 我有一个包含11838个客户端的数据库,并且此查询返回10404。我的问题是我无法使用C#linq复制此查询。

My C# query is as follows: 我的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();

This query returns 10563 results, a difference of 159, and I cannot figure out at all where I'm going wrong. 该查询返回10563个结果,相差159,并且我根本无法弄清楚哪里出了问题。 To me that C# query looks identical to the SQL one, but somewhere there is a discrepancy. 对我而言,C#查询看起来与SQL查询相同,但是在某些地方存在差异。 I've been coding all day, so maybe I'm a bit burnt out and the solution is obvious, but I just can't see it. 我整天都在编码,所以也许我有点精疲力尽,解决方案很明显,但是我看不到它。 Can anyone help, or suggest what I may be doing wrong or overlooking? 任何人都可以帮忙,或者建议我可能做错了或忽视了什么?

Answer 回答

As correctly pointed below by Matt Smith, it turns out both queries were correct - the discrepancy lay in the SQL DateDiff function, which measures 1 day as when the day passes midnight, which means comparing 01/01/2016 23:59:59 and 01/02/2016 00:00:01 gives a difference of one day, whereas in my C# query, it was comparing actual difference in days as a timespan (24hrs). 正如马特·史密斯(Matt Smith)在下面正确指出的那样,事实证明这两个查询都是正确的-差异在于SQL DateDiff函数,该函数将1天作为一天中的午夜,这意味着将01/01/2016 23:59:59与01/02/2016 00:00:01给出了一天的差异,而在我的C#查询中,它正在比较以天为单位的实际差异(24小时)。 Great find and important distinction to be made, thanks to Matt Smith. 感谢马特·史密斯(Matt Smith),这是一个伟大的发现和重要的区别。

Since I don't have your data, I can't be sure this works, but give this a go. 由于我没有您的数据,因此无法确定是否可行,但请尝试一下。 It should at least give you something to go with 它至少应该给你一些东西

    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();

You can also potentially make things easier on yourself by changing your Client entity to allow for nullable dates: 您还可以通过更改Client实体以允许可为空的日期来使事情变得更轻松:

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

Do you have time components in your date values? 您的日期值中有时间成分吗? If so, there are important differences between the way DateDiff works in SQL, where DateDiff(day, '03/06/2016 23:59:59', '03/07/2016 00:00:01') = 1, and .NET where ('03/07/2016 23:00:00' - '03/06/2016 23:59:00').Days = 0. DateDiff(day,x,y) measures the number of Day boundaries crossed. 如果是这样,则DateDiff在SQL中的工作方式之间存在重要区别,其中DateDiff(day,'03 / 06/2016 23:59:59','03 / 07/2016 00:00:01')= 1,和.NET where('03 / 07/2016 23:00:00'-'03 / 06/2016 23:59:00')。Days =0。DateDiff(day,x,y)测量跨越天边界的数量。 In .NET, the subtraction of DateTimes returns a TimeSpan of days, hours, minutes, seconds, milliseconds, and TimeSpan.Days returns the number of days in the TimeSpan. 在.NET中,DateTimes的减法返回天,小时,分钟,秒,毫秒和TimeSpan的TimeSpan.Days返回TimeSpan中的天数。

    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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM