C# 从LINQ到SQL调用SQL Server存储过程时,无法将nvarchar强制转换为datetime

C# 从LINQ到SQL调用SQL Server存储过程时,无法将nvarchar强制转换为datetime,c#,sql-server,linq,wcf,localization,C#,Sql Server,Linq,Wcf,Localization,我有一个应用服务器,它通过SQL server 2008R2连接到另一台服务器。这两个服务器的GUI都是法语的,并且日期和数字格式都是法语的。此外,用于执行命令语言的SQL Server和用户也被设置为法语(默认情况下均为法语)。但是,我将我的WCF服务中的格式设置为“en GB”,方法是将其放入web.config: 我在linqtosqldbcontext文件中包含了一个存储过程,我正在传递一个日期参数,而没有将其转换为字符串(因为ORM将其识别为date) 事情一直进展顺利,直到今天早些

我有一个应用服务器,它通过SQL server 2008R2连接到另一台服务器。这两个服务器的GUI都是法语的,并且日期和数字格式都是法语的。此外,用于执行命令语言的SQL Server和用户也被设置为法语(默认情况下均为法语)。但是,我将我的WCF服务中的格式设置为“en GB”,方法是将其放入web.config:

我在linqtosqldbcontext文件中包含了一个存储过程,我正在传递一个日期参数,而没有将其转换为字符串(因为ORM将其识别为date)

事情一直进展顺利,直到今天早些时候,程序停止执行,抛出一个异常,表示字符串不能转换为日期

我使用SQL Profiler跟踪了查询,发现它正在执行以下查询:

declare @p9 int
set @p9=NULL
exec sp_executesql N'EXEC @RETURN_VALUE = [GIS].[GetOnlineTrackingRecords] 
@CompanyId = @p0, @EntityIds = @p1, @MinDate = @p2, @MinRecordId = @p3, @TrackingType = @p4, @TrackAllEntities = @p5', N'@p0 int,@p1 varchar(8000),@p2 datetime,@p3 bigint,@p4 tinyint,@p5 bit,@RETURN_VALUE int output',
@p0=1,@p1='168',@p2='2013-10-24 16:36:28.690',@p3=NULL,@p4=1,@p5=0,@RETURN_VALUE=@p9 output 
select @p9
(关于@p2的主要问题)

包装存储过程的ORM方法如下所示:

[global::System.Data.Linq.Mapping.FunctionAttribute(Name= "GIS.GetOnlineTrackingRecords")]
public ISingleResult<FMS2.Framework.TrackEntities.GetOnlineTrackingRecordsResult> GetOnlineTrackingRecords([global::System.Data.Linq.Mapping.ParameterAttribute(Name="CompanyId", DbType="Int")] System.Nullable<int> companyId, [global::System.Data.Linq.Mapping.ParameterAttribute(Name="EntityIds", DbType="VarChar(MAX)")] string entityIds, [global::System.Data.Linq.Mapping.ParameterAttribute(Name="MinDate", DbType="DateTime")] System.Nullable<System.DateTime> minDate, [global::System.Data.Linq.Mapping.ParameterAttribute(Name="MinRecordId", DbType="BigInt")] System.Nullable<long> minRecordId, [global::System.Data.Linq.Mapping.ParameterAttribute(Name="TrackingType", DbType="TinyInt")] System.Nullable<byte> trackingType, [global::System.Data.Linq.Mapping.ParameterAttribute(Name="TrackAllEntities", DbType="Bit")] System.Nullable<bool> trackAllEntities)
    {
        IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), companyId, entityIds, minDate, minRecordId, trackingType, trackAllEntities);
        return ((ISingleResult<FMS2.Framework.TrackEntities.GetOnlineTrackingRecordsResult>)(result.ReturnValue));
    }
[global::System.Data.Linq.Mapping.FunctionAttribute(Name=“GIS.GetOnlineTrackingRecords”)]
public IsingResult GetOnlineTrackingRecords([global::System.Data.Linq.Mapping.ParameterAttribute(Name=“CompanyId”,DbType=“Int”)]System.Nullable CompanyId,[global::System.Data.Linq.Mapping.ParameterAttribute(Name=“EntityId”,DbType=“VarChar(MAX)”)string EntityId,[global::System.Data.Linq.Mapping.ParameterAttribute(Name=“MinDate”,DbType=“DateTime”)]System.Nullable minDate[global::System.Data.Linq.Mapping.ParameterAttribute(Name=“MinRecordId”,DbType=“BigInt”)]System.Nullable MinRecordId[global::System.Data.Linq.Mapping.ParameterAttribute(Name=“TrackingType”,DbType=“TinyInt”)]System.Nullable TrackingType[global::System.Data.Linq.Mapping.ParameterAttribute(Name=”trackallenties“,DbType=“Bit”)]系统。可为空的trackallenties)
{
IExecuteResult=this.ExecuteMethodCall(this,((MethodInfo)(MethodInfo.GetCurrentMethod())、companyId、EntityId、minDate、minRecordId、trackingType、Trackallenties);
返回((IsingResult)(result.ReturnValue));
}
当我尝试在SQL Server Management Studio中执行相同的查询时,它失败了,但是它在我的计算机上成功运行(使用英语SQL Server)。在我将SQL Server引擎的语言和用户默认语言更改为us_english后,它运行正常,但仅在SQL Server中运行,在从我的WCF应用程序调用时仍然失败,并显示相同的错误消息。我已使用sys.dm_exec再次检查是否在user with us_english language下执行查询_会话和SQL探查器。我已经读到,从'yyyy-MM-dd HH:MM:ss'字符串到目前为止的转换应该可以在任何机器上正常工作,但它似乎不是:( 考虑到触摸代码将非常困难,我下一步该怎么办


谢谢

您不应该传递像
yyyy-mm-dd hh:mm:ss
这样的字符串。原因如下:

SET LANGUAGE FRENCH;
SELECT CONVERT(DATETIME, '2013-05-06');
这将返回6月5日,而不是5月6日,因为它被解释为
yyyy-dd-mm
。如果您在日期(
'2013-10-24'
)中加入子项,则会出现错误,因为SQL Server不知道第24个月是什么

现在,我不知道如何在您的ORM中执行操作,但理想情况下,您永远不应该传递字符串,因此格式应该无关紧要。您应该传递日期/时间值,而不是字符串

当您确实需要传递一个字符串时(您也可以,因为我不知道您选择的ORM的局限性,我只知道没有ORM涵盖所有基础),您应该始终使用100%明确的格式。尝试:

@p2='2013-10-24T16:36:28.690'
---------------^ that T is important
让我解释一下原因,就为了阿里扎

如果日期和时间显示在同一行上,则始终将日期写在时间的前面。如果日期和时间值一起存储在单个数据字段中,则ISO 8601建议用拉丁大写字母T分隔,如19951231T235959所示


添加T时,SQL Server将无法以任何其他方式解释日期。这不是因为它是T,甚至不是因为ISO 8601的建议,而是因为SQL Server中的代码只是说,如果有T,则将日期解释为y-m-d,而不考虑区域、区域设置、日期格式或语言设置。

@Alireza为什么要这样做ep试图找到编辑我的答案的原因?如果你有什么要添加的,请随意添加评论。你的答案是好的和完整的,只需要对T进行一点澄清。也许有些读者看不到评论就知道什么是T。@Alireza你建议的编辑也不能真正解释T。如果你要编辑o其他人的回答,让这些编辑变得有价值。我添加的是一句简单的信息句子:T表示datetime值时间部分的开始。你真的认为它没有解释“T”吗?@AaronBertrand OP没有转换为字符串。这是linq to sql做的。