2009-07-21 77 views
1

我已经创建了下面的LINQ查询来演示该问题怪异的结果:LINQ的OrderBy子句导致

string[] dateStrings = new string[] { "2009-07-20 13:00:00", "2009-07-20 16:00:00", "2009-07-20 09:00:00" }; 

DateTime dateValue = DateTime.MinValue;  

var results = 
    from dateString in dateStrings 
    where DateTime.TryParse(dateString, out dateValue) 
    orderby dateValue descending 
    select dateValue; 

你所期望的结果是DateTime是否在相反的顺序列表:
20- 7-2009 16:00:00
20-7-2009 13:00:00
20-7-2009 9:00:00

但是我得到的是这样的:
20-7-2009 9:00:00
20-7-2009 9:00:00
20-7-2009 9:00:00

我在做什么错? 如果您删除orderby语句,您会注意到一个DateTime的正常列表。

回答

10

dateValue声明在哪里?注意到它只能保存一个值。

试试这个:

string[] dateStrings = new string[] { "2009-07-20 13:00:00", 
    "2009-07-20 16:00:00", "2009-07-20 09:00:00" }; 

var results = 
dateStrings.Select(s => 
{ 
    DateTime v; 
    bool parsed = DateTime.TryParse(s, out v); 
    return new {Parsed = parsed, Value = v }; 
}) 
.Where(x => x.Parsed) 
.Select(x => x.Value) 
.OrderByDescending(d => d); 
+0

抱歉忘记在这个例子中输入。我已经更新了这个问题。没有秩序,一切都很好。 – Zyphrax 2009-07-21 12:43:07

+1

orderby必须在订购可能继续之前急切地解决该点之上的查询。在where条款处理了所有三条记录之后,dateValue的值已经获得它的最终值。然后orderby操作并按该值排序。然后选择操作并投影一个值3次。 – 2009-07-21 12:46:17

0

VAR的结果= 从dateString在dateStrings 其中DateTime.TryParse(dateString,出DATEVALUE) 排序依据DATEVALUE下降 选择DATEVALUE;

我相信Linq对查询使用延迟执行,但对TryParse不使用,因此只有在查询实际执行时才从TryParse获取Date的最后一个值。

尝试将日期解析到一个数组中,然后使用适当的Linq构造来执行相应的逻辑。

6

尝试方法

 var results = 
      from dateString in dateStrings 
      orderby (Convert.ToDateTime(dateString)) descending 
      select (Convert.ToDateTime(dateString)); 
1

orderby子句要求where子句首先执行。在where之后应用orderby,它需要执行orderby操作的所有结果。因此dateValue将总是包含最后的,其中结果。

这里有一个解决方案:

 var results = from date in 
          (
           from dateString in dateStrings 
           where DateTime.TryParse(dateString, out dateValue) 
           select dateValue 
          ) 
         orderby date descending 
         select date; 
1

我在阅读上的Visual Studio 2008的起始页的主题,发现一对“让”关键字的话题。这给我带来了以下解决方案:

string[] dateStrings = new string[] { "2009-07-20 13:00:00", "2009-07-20 16:00:00", "2009-07-20 09:00:00" }; 

DateTime dateVal = DateTime.MinValue; 

var results = 
from dateString in dateStrings 
where DateTime.TryParse(dateString, out dateVal) 
let dateValue = dateVal 
orderby dateValue descending 
select dateValue; 

请注意,我所做的只是添加行,并相应地重命名变量:

let dateValue = dateVal 

很简单,有效。