Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

i'm learning the book:

LINQ to Objects Using C# 4.0

Ok, my question:

I have two class: Contact and CallLog. It look like:

public class Contact
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Email { get; set; }
        public string Phone { get; set; }
        public DateTime DateOfBirth { get; set; }
        public string State { get; set; }
};

public class CallLog
    {
        public string Number { get; set; }
        public int Duration { get; set; }
        public bool Incoming { get; set; }
        public DateTime When { get; set; }
    }

Relation: Contact.Phone equals CallLog.Number

Two Class have method: SampleData(). This metod return a simple List<> with Contacts and CallLogs.

List<Contact> contacts = Contact.SampleData();
List<CallLog> callLogs = CallLog.SampleData();

I have now query, which return a result sort by numbers of calls foreach Contact (exactly contact, who calls more that 0).

var query = (from callLog in callLogs
                        group callLog by callLog.Number into g
                        select new
                        {
                            contact = contacts.Where(c=>c.Phone == g.Key),
                            how_much = g.Count(),
                        });

foreach(var q in query){
     foreach(var qq in q.contact){
          Console.WriteLine(qq.FirstName + " calls " + q.how_much + " times");
     }
}

It return for example:

Stephan calls 5 times

Sophie calls 2 times

Tom calls 5 times

etc...

now I want to group by time of calls (5 times, 2 times ...), well i'm writin next query by query:

var query2 = from q in query
                         group q by q.how_much into g
                         select new
                         {
                             what_number       = g.Key, // f.e 5 times
                             count_what_number = g.Count(), // 5 times have 2 person
                             who               = g // collection for person
                         };
foreach (var q in query2)
            {
                Console.WriteLine(q.what_number + " calls have done: ( " + q.count_what_number + ") peoples"));
                foreach (var qq in q.who)
                {
                    foreach (var qqq in qq.contact)
                    {
                        Console.WriteLine("   " + qqq.FirstName);
                    }
                }
            }

result:

5 calls have done: (2 peoples):
     Stephan
     Tom
2 calls have done: (1 peoples):       
     Sophie

It's any way to make this query by 1 query (group by group not in two queries)?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
133 views
Welcome To Ask or Share your Answers For Others

1 Answer

Here is another way to do that:

List<Contact> contacts = Contact.SampleData();
List<CallLog> callLogs = CallLog.SampleData();

var q = from callLog in callLogs
        group callLog by callLog.Number into g
        join c in contacts on g.Key equals c.Phone
        let row = new { g = g, c = c }
        group row by row.g.Count() into g2
        select new
        {
            People = g2.Select((x) => x.c.FirstName).ToArray(),
            Count = g2.Key
        };

foreach (var qq in q)
{
    Console.WriteLine(qq.Count + ": " + string.Join(", ", qq.People));
}

Prints something like:

4: Tom, John
2: Adam

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...