Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在Linq中将DateTimeOffset转换为DateTime_C#_Sql Server_Linq - Fatal编程技术网

C# 如何在Linq中将DateTimeOffset转换为DateTime

C# 如何在Linq中将DateTimeOffset转换为DateTime,c#,sql-server,linq,C#,Sql Server,Linq,我有一个返回错误结果的查询: return contextProvider .Context .OrderAccounts .Where(orderAccount => listCSRId.Contains(orderAccount.OrderCust.UserId) &&

我有一个返回错误结果的查询:

 return contextProvider
                      .Context
                      .OrderAccounts
                      .Where(orderAccount => listCSRId.Contains(orderAccount.OrderCust.UserId) &&
                                    orderAccount.OrderCust.SubmittedDate >= System.Data.Entity.DbFunctions.TruncateTime(startDate)
                                    && orderAccount.OrderCust.SubmittedDate <= startDate
                                    && orderAccount.OrderCust.OrderStatusId == (int)OrderStatus.Submitted)
                       .Select(x => new Order
                       {
                         UserId = x.OrderCust.UserId,
                         FacilityCode = x.FacilityCode,
                         GreenFlag = x.GreenFlag ?? false,
                         Payable = x.Payable,
                         OrderCustId = x.OrderCustId
                       })
                      .ToList();
结果不正确的原因是SubmittedDate是Sql Server中的DateTimeOffSet。因此,当存储2017年11月15日晚上11点的本地日期时间时,由于本地时间和格林尼治标准时间之间的偏移,它将存储为2017年11月16日04:00

当查询运行时,startDate只是一个没有时间的日期。因此,需要将表中的SubmittedDate转换为本地日期。那么这个查询就正确了

如何做到这一点?

将起始日期转换为UTC,并添加1天,转换并确保提交日期介于两者之间:

return contextProvider
                      .Context
                      .OrderAccounts
                      .Where(orderAccount => listCSRId.Contains(orderAccount.OrderCust.UserId) &&
                                    orderAccount.OrderCust.SubmittedDate >= System.Data.Entity.DbFunctions.TruncateTime(startDate.ToUniversalTime())
                                    && orderAccount.OrderCust.SubmittedDate < startDate.AddDays(1).ToUniversalTime()
                                    && orderAccount.OrderCust.OrderStatusId == (int)OrderStatus.Submitted)
                       .Select(x => new Order {
                           UserId = x.OrderCust.UserId,
                           FacilityCode = x.FacilityCode,
                           GreenFlag = x.GreenFlag ?? false,
                           Payable = x.Payable,
                           OrderCustId = x.OrderCustId
                       })
                      .ToList();

问题是“startDate”参数是DateTime,而不是DateTimeOffset

当此参数更改为DateTimeOffset时,查询开始正常工作

换句话说,将值为2017-11-15 00:00且偏移量为-5:00的DateTimeOffset转换为2017-11-15 05:00且无偏移量的UTC。我认为EntityFramework/Sql Server足够聪明,可以正确地比较DateTimeOffset,它可以在没有偏移的情况下转换为UTC

因此,现在返回任何大于2017-11-15 05:00的提交日期,这就是我想要的当前日期记录-当地时间为2017-11-15 00:00

时间是一个很难把握的话题,希望我已经正确地解释了这一点


方法是:将Sql Server DateTimeOffset与.net DateTimeOffset进行比较,而不是与DateTime进行比较。

为什么不将startDate转换为DateTimeOffset呢?这就是为什么您应该始终在数据库中以UTC存储DateTimes的原因。其他一切都是表示,不属于您的数据库。我意识到这并不能回答你的问题,但它本可以避免,因为时间部分没有被使用。我需要在某个日期提交所有订单,无论何时。如果我转换为DateTimeOffset,然后删除时间部分,它现在将返回错误日期的订单。我尝试了这个,但它对我不起作用。请参见下面的内容。-1因为海报没有验证他或她的假设,即ToUniversalTime是受支持的EF操作,而不是System。NotSupportedException:LINQ to Entities不识别方法“System.DateTimeOffset ToUniversalTime”方法,而且这个方法不能转换成存储表达式。@PaulMSorauer什么让你认为EF是相关的?另外,startDate是一个本地值,而不是SQL列中的EF字段,因此应该在客户机上计算表达式。使用LINQ to SQL/EF Core 2.2.6/EF Core 3.1进行的快速测试表明,该方法工作正常。抱歉。正如你所指出的,我实际上没有意识到startDate是一个局部变量,当我在EF 6中测试时,我在DB中使用了datetimeoffset,这就是它失败的原因。为我的误会道歉。我想把这件事投回去。