使用LINQ对列表进行分组和排序

时间:2013-05-17 11:36:18

标签: linq c#-4.0

我有一个包含以下内容的消息结构

DateTime dateIn;
long? messageId;
string messageContent;

我正在尝试根据messageId对消息列表进行分组,并按dateIn字段排序。

我的LINQ目前看起来像这样

var groups = from c in MessageList 
            let name = c.messageId
                orderby name ascending, c.dateIn ascending
                group c by name into g
                select g;

当我尝试将其反馈到新的列表<消息>,编译器返回

  

“无法隐式转换类型System.Collections.Generic.List<   System.Linq.IGrouping<很长?,消息> >至   System.Collections.Generic.List<邮件>“

问题长期存在吗?比什么都重要?我试图将messageId强制转换为long,但这似乎也不起作用。

2 个答案:

答案 0 :(得分:2)

我想你可以使用SelectMany从分组的那个中收集你的Message集合(如果我理解你的话):

List<Messages> back = groups.SelectMany(m=>m.ToList()).ToList();

<强>已更新

根据你的意见。当您使用 GroupBy 时 - Linq会根据您用于分组的集合类型和密钥类型创建新的通用类型的Enumerable。在你的情况下它是消息类型和长? (messageId的类型 - 密钥,您正在分组)。所以这对你有用:

List<long?,Messages> grouped = groups.ToList();

或者您可以使用 var ,这也可以使用:

var grouped = groups.ToList();

答案 1 :(得分:1)

如果我明白你想做什么,那就有更简单的方法。看看我的演示:

public class Program
{
    static void Main(string[] args)
    {
        List<Message> MessageList = new List<Message>()
        {
            new Message(){ dateIn = new DateTime(2000,1,11)},
            new Message(){ dateIn = new DateTime(2000,1,9)},
            new Message(){ dateIn = new DateTime(2000,1,8), messageId = 5},
            new Message(){ dateIn = new DateTime(2000,1,12)},
            new Message(){ dateIn = new DateTime(2000,1,2), messageId = 7}
        };

        foreach (var item in MessageList)
        {
            Console.WriteLine(item);
        }

        Console.WriteLine("===");

        // MUCH SIMPLER
        var result = MessageList
            .GroupBy(m => m.messageId)
            .SelectMany(m => m.ToList())
            .OrderBy(m => m.dateIn);

        foreach (var item in result)
        {
            Console.WriteLine(item);
        }

        Console.ReadLine();
    }
}

struct Message
{
    public DateTime dateIn { get; set; }
    public long? messageId { get; set; }
    public string messageContent { get; set; }

    public override string ToString()
    {
        return messageId + "\t" + dateIn;
    }
}