C# 使用其他区域性时进行错误的日期时间分析
我在一个多语言站点中使用EF将结果从SP映射到对象C# 使用其他区域性时进行错误的日期时间分析,c#,.net,sql-server,entity-framework,invariantculture,C#,.net,Sql Server,Entity Framework,Invariantculture,我在一个多语言站点中使用EF将结果从SP映射到对象 ctx.Database.SqlQuery<MyDTO>("MySP {0}", Id).SingleOrDefault() ctx.Database.SqlQuery(“MySP{0}”,Id).SingleOrDefault() 我发现当文化发生变化时,映射日期存在问题 更具体地说,根据用户文化,我得到的日期与16/12/2015 09:06:15或12/16/2015 09:06:15相同 我知道两种解决方案: 以字符串
ctx.Database.SqlQuery<MyDTO>("MySP {0}", Id).SingleOrDefault()
ctx.Database.SqlQuery(“MySP{0}”,Id).SingleOrDefault()
我发现当文化发生变化时,映射日期存在问题
更具体地说,根据用户文化,我得到的日期与16/12/2015 09:06:15
或12/16/2015 09:06:15
相同
我知道两种解决方案:
- 以字符串形式获取日期,并使用
对其进行解析CultureInfo.InvariantCulture
- 在调用存储库方法之前,将区域性切换到
CultureInfo.CultureInvariant
- 我看到我们将:
和Thread.CurrentThread.CurrentUICulture
都更改为用户的区域设置,但我认为我们应该只切换一个UI。但我不确定如果我改变了这个,会发生什么Thread.CurrentThread.CurrentCulture
更新:
在执行查询之前更改
Thread.CurrentThread.CurrentUICulture
和Thread.CurrentThread.CurrentCulture
似乎也没有帮助。这让人困惑。。。也许EF会在较早的时候缓存区域性?首先,您应该避免这样调用存储过程-这是解决Sql注入安全问题的一种简单方法
相反,您应该通过将参数作为实际参数传递给存储过程来调用,例如:
string dateAsString = "12/16/2015 09:06:15";
string dateFormat = "MM/dd/yyyy HH:mm:ss";
DateTime theValue = DateTime.Parse(dateAsString, dateFormat, CultureInfo.InvariantCulture);
SqlParameter myDate = new SqlParameter("@theDate", theValue);
context.Database.ExecuteSqlCommand("MySP @theDate", theDate);
您可以将日期时间存储为long(柚木)或real(将日期时间转换为real时得到的数字)。然后,您可以将这些值毫无损失地转换为任何区域性。我最终找到了这个值。:) 我正在手表中查看
DateTime
s的值。这就是问题所在。。。看起来手表使用当前线程的区域性(从而将月和日的顺序从区域性切换到区域性)。结果证明日期是正确的(如果你认为16是月…………<代码> 12/16/2015 09:06:15无论如何都不是一个有效的日期……
所以,VS观察家让我迷失了方向
很高兴知道,当前线程区域性不会像我预期的那样影响SQL数据的解析。:)
实际的错误后来出现在代码中。我的印象是,
ctx.Database.SqlQuery
在设计上阻止了SQL注入,它与String.Format
不同。我认为微软将如此高风险的东西投入EF是非常幼稚的。你确定我的方法真的有问题吗?例如,请看这里:(我希望我能在MSDN中找到一个关于这方面的例子…)。我现在没有时间测试它,我个人在将参数传递给ORM之前,我会尽我所能处理它们,以防万一。。。。在任何情况下,无论是否存在安全问题,解析日期并将其作为参数传递都应该可以解决您的问题,如本答案中所述……谢谢,但我无法更改数据库。:)如果始终将日期时间数据视为日期时间数据,则不应该存在问题。只有将数据转换为字符串时,才会出现格式问题。尽量避免转换。那么,你一开始是如何得到像12/16/2015 09:06:15
这样的字符串的呢?@Damien_the_unsiver Hi。我终于想出了这个办法。:)我没有使用字符串,我只是在手表中查看DateTime
s的值。这就是问题所在。。。看起来手表使用了当前线程的区域性。结果证明日期是正确的(这:12/16/2015 09:06:15
无论如何都不能是一个有效的日期…意识到这一点永远不会太晚…:D)。该错误后来出现在代码中。我会把答案贴在下面。