我的查询如下:
using (var ctx = new PCLvsCompContext())
{
var brokerId = broker?.Id;
var symbolId = company?.Id;
var result = (from t in ctx.TradeHistoryJoineds
where t.TradeDate >= fromDate
&& t.TradeDate <= toDate
&& (brokerId == null || t.BrokerId == brokerId)
&& (symbolId == null || t.SymbolId == symbolId)
select t).OrderBy(x => x.TradeDate).ThenBy(x => x.BrokerName).ToList();
return result;
}
例如,我运行此查询的日期类似于fromDate March-01-2017 toDate March-31-2017。然后我捕获了SQL查询器中生成的sql,该查询生成并在SQL管理工作室中运行它。产量如预期,每个工作日,每家公司都有一些交易。该查询基于一个视图,该视图将所有日期转换为“datetime”,以便excel可以正确地将它们解析为日期。但是,当我在“返回结果”处设置断点并检查日期时,除了2个日期之外的所有日期都是3月1日到2017年3月1日。这是不正确的,SQL管理器中的查询结果几乎每个工作日都显示交易(这是正确的)。
这里发生了什么? Linq为什么会失去理智?
答案 0 :(得分:1)
虽然根据结果我无法确切地看到你最终会得到这些结果,但是你可能正在处理DateTime
时区问题。我怀疑您可能使用来自DateTime
而不是DateTime.Now
的{{1}}对象将日期保存到数据库中。因此,在那个时间点并且基于机器调用它将基于该机器的时区和日期节省。
不应使用DateTime.UtcNow
对象,因为它可能与SQL数据库的区域有关,该区域是进行此LINQ调用的服务器区域,因此这两个区域可能位于不同的时区。
相反,您应该始终使用DateTime
。
如果由于某种原因你不能这样做,那么仔细检查你的日期toDate和fromDate并做:
DateTimeOffset
如果它是在2018年4月3日22:56运行的话,那就是这样的。
var utcToDate = toDate.ToUniversalTime().ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'");
var utcFromDate = toDate.ToUniversalTime().ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'");
然后,您还需要确保何时将任何日期保存到您首先执行ToUniversalTime()的SQL后备存储。您可以使用普通的SQL查询直接检查SQL表,它们应该以与上面相同的UTC字符串格式存储在数据库中,然后比较它应该是否有效。
但是我强烈建议您更改所有DateTime电话并转到
2018-04-03T22:56:57.740Z
。在大多数情况下,唯一一次使用DateTimeOffset
是为了最终显示给用户。
答案 1 :(得分:0)
谢谢大家的建议。对于那些谁熟悉LINQ,EF和看法这似乎是一个愚蠢的监督,但我会后我的羞辱他人的情况下,这种情况给他们,因为事业和结果的行为没有立即明显联系(可以看出通过所有建议,其中没有一个真正指出答案)。
当要查询使用LINQ和实体框架的视图,则显然必须有一个称为列&#39;标识&#39 ;,否则实体框架可&#39;吨彼此区分的任何行的和简单地使某些重复我无法解读(即使没有Id列,所有行都基于他们的数据是唯一的,因此我无法弄清楚为什么这是必要的。)
所以通过添加一个带有&#39; Id&#39;的TradeId。视图的别名,然后实体框架似乎恢复理智并按预期映射数据。