LINQ Orderby子句导致奇怪的结果

时间:2009-07-21 12:35:35

标签: c# linq

我创建了以下LINQ查询来演示问题:

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;

您希望结果是颠倒顺序的DateTimes列表:
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的正常列表。

6 个答案:

答案 0 :(得分: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);

答案 1 :(得分:6)

尝试方法

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

答案 2 :(得分:3)

这是由延迟执行引起的。

dateValue只能有一个值,这将是dateStrings中的最后一个值。

阅读Closures上的以下文章,了解原因:

http://diditwith.net/2007/09/25/LINQClosuresMayBeHazardousToYourHealth.aspx

答案 3 :(得分:1)

orderby子句要求首先执行where子句。 orderby之后正在应用where,它需要所有结果来执行orderby操作。因此,dateValue将始终包含最后结果。

这是一个解决方案:

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

答案 4 :(得分:1)

我正在阅读Visual Studio 2008起始页面上的主题,并注意到有关“let”关键字的主题。这让我想到了下面的解决方案:

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

非常简单有效。

答案 5 :(得分:0)

  

var results =      来自dateStrings中的dateString      其中DateTime.TryParse(dateString,out dateValue)      orderby dateValue降序      选择dateValue;

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

尝试将日期解析为数组,然后使用适当的Linq构造来执行逻辑。