Nodoid
Nodoid

Reputation: 1561

Grouping and ordering a list using LINQ

I have a message structure that contains the following

DateTime dateIn;
long? messageId;
string messageContent;

I am trying to group my message list based on messageId and ordered by the dateIn field.

My LINQ currently looks like this

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

When I try and feed it back into a new List< Messages>, the compiler comes back with

"Cannot implicitly convert type System.Collections.Generic.List< System.Linq.IGrouping < long?, Messages> > to System.Collections.Generic.List< Messages>"

Is the problem down to the long? more than anything? I have tried to cast messageId to long, but that doesn't seem to work either.

Upvotes: 1

Views: 613

Answers (2)

Alex
Alex

Reputation: 8937

I suppose you can use SelectMany to orbitaine your Message collection from the grouped one (if I understood you correct):

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

UPDATED

According to your comments. When you use GroupBy - Linq creates the Enumerable of new generic type combining your collection type and key type, which you use for grouping. In your case it is Messages type and long? (the type of messageId - key, you are grouping by). So this should work for you:

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

Or you can use var and this should work also:

var grouped = groups.ToList();

Upvotes: 2

astef
astef

Reputation: 9478

If I understand what are you trying to do, there is simpler way. Look at my demo:

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;
    }
}

Upvotes: 1

Related Questions