Hooked on LINQ

Hooked on LINQ - Developers' Wiki
for .NET Language Integrated Query

Companion book for this site
LINQ to Objects Using C# 4.0:
Using and Extending LINQ to Objects and Parallel LINQ (PLINQ)
Quick Search

Advanced Search »
Edit

Chapter 1 - Introducing LINQ





Edit

Grouping and Sorting Contact Records

Edit

Listing 1-1 : C# 2.0 code for grouping and sorting contact records

This sample uses traditional C#2.0 code to group and sort a List records.

public void Listing_1_1()
{
    List<Contact> contacts = Contact.SampleData();
 
    // sort by last name
    contacts.Sort(
        delegate(Contact c1, Contact c2)
        {
            if (c1 != null && c2 != null)
                return string.Compare(
                    c1.LastName, c2.LastName);
            
            return 0;
        }
    );
 
    // sort and group by state (using a sorted dictionary)
    SortedDictionary<string, List<Contact>> groups =
        new SortedDictionary<string, List<Contact>>();
 
    foreach (Contact c in contacts)
    {
        if (groups.ContainsKey(c.State))
        {
            groups[c.State].Add(c);
        }
        else
        {
            List<Contact> list = new List<Contact>();
            list.Add(c);
            groups.Add(c.State, list);
        }
    }
 
    // write out the results
    foreach (KeyValuePair<string, List<Contact>> 
        group in groups)
    {
        Console.WriteLine("State: " + group.Key);
        foreach (Contact c in group.Value)
            Console.WriteLine(" {0} {1}", c.FirstName, c.LastName);
    }
}
 
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 static List<Contact> SampleData()
    {
        return new List<Contact> {
            new Contact {FirstName = "Barney",     LastName = "Gottshall",     DateOfBirth = new DateTime(1945,10,19), Phone = "885 983 8858", Email = "bgottshall@aspiring–technology.com", State = "CA" },
            new Contact {FirstName = "Armando",    LastName = "Valdes",        DateOfBirth = new DateTime(1973,12,09), Phone = "848 553 8487", Email = "val1@aspiring–technology.com", State = "WA" },
            new Contact {FirstName = "Adam",       LastName = "Gauwain",       DateOfBirth = new DateTime(1959,10,03), Phone = "115 999 1154", Email = "adamg@aspiring–technology.com", State = "AK" },
            new Contact {FirstName = "Jeffery",    LastName = "Deane",         DateOfBirth = new DateTime(1950,12,16), Phone = "677 602 6774", Email = "jeff.deane@aspiring–technology.com", State = "CA" },
            new Contact {FirstName = "Collin",     LastName = "Zeeman",        DateOfBirth = new DateTime(1935,02,10), Phone = "603 303 6030", Email = "czeeman@aspiring–technology.com", State = "FL" },
            new Contact {FirstName = "Stewart",    LastName = "Kagel",         DateOfBirth = new DateTime(1950,02,20), Phone = "546 607 5462", Email = "kagels@aspiring–technology.com", State = "WA" },
            new Contact {FirstName = "Chance",     LastName = "Lard",          DateOfBirth = new DateTime(1951,10,21), Phone = "278 918 2789", Email = "lard@aspiring–technology.com", State = "WA" },
            new Contact {FirstName = "Blaine",     LastName = "Reifsteck",     DateOfBirth = new DateTime(1946,05,18), Phone = "715 920 7157", Email = "blaine@aspiring–technology.com", State = "TX" },
            new Contact {FirstName = "Mack",       LastName = "Kamph",         DateOfBirth = new DateTime(1977,09,17), Phone = "364 202 3644", Email = "mack.kamph@aspiring–technology.com", State = "TX" },
            new Contact {FirstName = "Ariel",      LastName = "Hazelgrove",    DateOfBirth = new DateTime(1922,05,23), Phone = "165 737 1656", Email = "arielh@aspiring–technology.com", State = "OR" }
        };
    }
}
 

Console output (Execution time: 14ms): [Hide/Show]


Top



Edit

Listing 1-2 : C# 3.0 LINQ to objects code for grouping and sorting contact records

This sample uses LINQ to Objects C# 3.0 code to group and sort a List records.

public void Listing_1_2()
{
    List<Contact> contacts = Contact.SampleData();
 
    // perform the LINQ query
    var query = from c in contacts
                orderby c.State, c.LastName
                group c by c.State;
 
    // write out the results
    foreach (var group in query)
    {
        Console.WriteLine("State: " + group.Key);
        foreach (Contact c in group)
            Console.WriteLine(" {0} {1}",
                c.FirstName, c.LastName);
    }
}
 
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 static List<Contact> SampleData()
    {
        return new List<Contact> {
            new Contact {FirstName = "Barney",     LastName = "Gottshall",     DateOfBirth = new DateTime(1945,10,19), Phone = "885 983 8858", Email = "bgottshall@aspiring–technology.com", State = "CA" },
            new Contact {FirstName = "Armando",    LastName = "Valdes",        DateOfBirth = new DateTime(1973,12,09), Phone = "848 553 8487", Email = "val1@aspiring–technology.com", State = "WA" },
            new Contact {FirstName = "Adam",       LastName = "Gauwain",       DateOfBirth = new DateTime(1959,10,03), Phone = "115 999 1154", Email = "adamg@aspiring–technology.com", State = "AK" },
            new Contact {FirstName = "Jeffery",    LastName = "Deane",         DateOfBirth = new DateTime(1950,12,16), Phone = "677 602 6774", Email = "jeff.deane@aspiring–technology.com", State = "CA" },
            new Contact {FirstName = "Collin",     LastName = "Zeeman",        DateOfBirth = new DateTime(1935,02,10), Phone = "603 303 6030", Email = "czeeman@aspiring–technology.com", State = "FL" },
            new Contact {FirstName = "Stewart",    LastName = "Kagel",         DateOfBirth = new DateTime(1950,02,20), Phone = "546 607 5462", Email = "kagels@aspiring–technology.com", State = "WA" },
            new Contact {FirstName = "Chance",     LastName = "Lard",          DateOfBirth = new DateTime(1951,10,21), Phone = "278 918 2789", Email = "lard@aspiring–technology.com", State = "WA" },
            new Contact {FirstName = "Blaine",     LastName = "Reifsteck",     DateOfBirth = new DateTime(1946,05,18), Phone = "715 920 7157", Email = "blaine@aspiring–technology.com", State = "TX" },
            new Contact {FirstName = "Mack",       LastName = "Kamph",         DateOfBirth = new DateTime(1977,09,17), Phone = "364 202 3644", Email = "mack.kamph@aspiring–technology.com", State = "TX" },
            new Contact {FirstName = "Ariel",      LastName = "Hazelgrove",    DateOfBirth = new DateTime(1922,05,23), Phone = "165 737 1656", Email = "arielh@aspiring–technology.com", State = "OR" }
        };
    }
}
 

Console output (Execution time: 6ms): [Hide/Show]


Top



Edit

Creating Summary XML for Data

Edit

Listing 1-3 : C# 2.0 code for summarizing data, joining to a second collection and writing out XML

C# 2.0 style code for summarizing data and joining data from two collections and writing out the results in XML form.

public void Listing_1_3_SummarizingDataFromMultipleCollections()
{
    List<Contact> contacts = Contact.SampleData();
    List<CallLog> callLog = CallLog.SampleData();
 
    // group incoming calls by phone number 
    Dictionary<string, List<CallLog>> callGroups 
        = new Dictionary<string, List<CallLog>>();
 
    foreach (CallLog call in callLog)
    {
        if (callGroups.ContainsKey(call.Number))
        {
            if (call.Incoming == true)
                callGroups[call.Number].Add(call);
        }
        else
        {
            if (call.Incoming == true)
            {
                List<CallLog> list = new List<CallLog>();
                list.Add(call);
                callGroups.Add(call.Number, list);
            }
        }
    }
 
    // sort contacts by last name, then first name
    contacts.Sort(
        delegate(Contact c1, Contact c2)
        {
            // compare last names
            int result = c1.LastName.CompareTo(c2.LastName);
 
            // if last names match, compare first names
            if (result == 0)
                result = c1.FirstName.CompareTo(c2.FirstName);
 
            return result;
        });
 
    // prepare and write XML document
    using (StringWriter writer = new StringWriter())
    {
        using (XmlTextWriter doc = new XmlTextWriter(writer))
        {
            // prepare XML header items
            doc.Formatting = Formatting.Indented;
            doc.WriteComment("Summarized Incoming Call Stats");
            doc.WriteStartElement("contacts");
 
            // join calls with contacts data
            foreach (Contact con in contacts)
            {
                if (callGroups.ContainsKey(con.Phone))
                {
                    List<CallLog> calls = callGroups[con.Phone];
                
                    // calculate the total call duration and average
                    long sum = 0;
                    foreach (CallLog call in calls)
                        sum += call.Duration;
 
                    double avg = (double)sum / (double)calls.Count;
 
                    // write XML record for this contact
                    doc.WriteStartElement("contact");
                    
                    doc.WriteElementString("lastName", 
                        con.LastName);
                    doc.WriteElementString("firstName", 
                        con.FirstName);
                    doc.WriteElementString("count", 
                        calls.Count.ToString());
                    doc.WriteElementString("totalDuration", 
                        sum.ToString());
                    doc.WriteElementString("averageDuration", 
                        avg.ToString());
                    
                    doc.WriteEndElement();
                }
            }
 
            doc.WriteEndElement();
            doc.Flush();
            doc.Close();
        }
 
        Console.WriteLine(writer.ToString());
    }
}
 

Console output (Execution time: 15ms): [Hide/Show]


Top



Edit

Listing 1-4 : C# 3.0 LINQ to Objects code for summarizing data, joining to a second collection, and writing out XML

LINQ style code for summarizing data and joining data from two collections and writing out the results in XML form.

public void Listing_1_4_SummarizingDataFromMultipleCollections()
{
    List<Contact> contacts = Contact.SampleData();
    List<CallLog> callLog = CallLog.SampleData();
 
    var q = from call in callLog
            where call.Incoming == true
            group call by call.Number into g
            join contact in contacts on
                 g.Key equals contact.Phone
            orderby contact.LastName, contact.FirstName
            select new XElement("contact",
                     new XElement("lastName",
                         contact.LastName),
                     new XElement("firstName",
                         contact.FirstName),
                     new XElement("count",
                          g.Count()),
                     new XElement("totalDuration",
                         g.Sum(c => c.Duration)),
                     new XElement("averageDuration",
                        g.Average(c => c.Duration))
                        );
 
    // create the XML document and add the items in query q
    // (any IEnumerable source will cause an element to be 
    // written for each item in that source (each contact).
    XDocument doc = new XDocument(
        new XComment("Summarized Incoming Call Stats"),
        new XElement("contacts", q)
    );
 
    Console.WriteLine(doc.ToString());
}
 

Console output (Execution time: 27ms): [Hide/Show]


Top



Edit

Creating an RSS Feed of Order Data from SQL Server

Edit

Listing 1 : Traditional C# 2.0 ADO.Net and XML Code.

This sample uses ADO.Net and XML code to build an RSS file string for Order data. This example is not included in the book.

public void Listing_1_ADONet_RSS_Example()
{
    // using SQL rather than stored procedures for this example. 
    // however, this only alters only these lines – using SP's is the right way!
    const string sql =
        @"SELECT TOP (5) o.OrderID, o.OrderDate, c.ContactName 
                      FROM Orders AS o 
                        INNER JOIN Customers AS c ON 
                            o.CustomerID = c.CustomerID 
                      ORDER BY o.OrderDate DESC";
 
    const string sqlDetails =
        @"SELECT od.Quantity, p.ProductName 
                      FROM Order Details AS od 
                        INNER JOIN Products AS p ON 
                            od.ProductID = p.ProductID 
                      WHERE od.OrderID = @orderID";
 
    using (StringWriter writer = new StringWriter())
    {
        using (XmlTextWriter doc = new XmlTextWriter(writer))
        {
            // add the header items
            doc.Formatting = Formatting.Indented;
            doc.WriteStartDocument();
            doc.WriteComment("Real–Time Orders RSS Feed");
            doc.WriteStartElement("rss");
            doc.WriteAttributeString("version", "2.0");
            doc.WriteStartElement("channel");
            doc.WriteElementString("title", "Orders RSS Title");
            doc.WriteElementString("description", "Recent Orders.");
            doc.WriteElementString("link",
                "http://HookedOnLinq.com");
 
            // build the item elements
            using (SqlConnection connection =
                new SqlConnection(connString))
            {
                connection.Open();
 
                SqlCommand command = new SqlCommand(sql, connection);
                SqlDataReader reader = command.ExecuteReader();
                while (reader != null && reader.Read())
                {
                    doc.WriteStartElement("item");
 
                    doc.WriteElementString("title",
                          string.Format("Order {0} from {1}",
                                    reader["OrderID"],
                                    reader["ContactName"]
                                    ));
 
                    // build the order detail summary string
                    string detail = "";
                    using (SqlConnection conn2 = new SqlConnection(connString))
                    {
                        conn2.Open();
                        SqlCommand detailcommand = new SqlCommand(sqlDetails, conn2);
                        SqlParameter param = new SqlParameter(
                            "orderID", reader["OrderID"]);
                        detailcommand.Parameters.Add(param);
                        SqlDataReader details = detailcommand.ExecuteReader();
                        while (details != null && details.Read())
                        {
                            detail +=
                                details["Quantity"].ToString() +
                                " x " + details["ProductName"] + ". ";
                        }
                        details.Close();
                    }
 
                    doc.WriteElementString("description",
                        detail);
 
                    doc.WriteElementString("pubdate",
                        ((DateTime.Parse(
                            reader["OrderDate"].ToString()))
                        .ToUniversalTime())
                        .ToString("u")
                        );
 
                    doc.WriteElementString("guid",
                        reader["OrderID"].ToString());
 
                    doc.WriteEndElement();
                }
                reader.Close();
                connection.Close();
            }
 
            doc.WriteEndElement();
            doc.WriteEndElement();
            doc.WriteEndDocument();
            doc.Flush();
            doc.Close();
 
            Console.WriteLine(writer.ToString());
        }
    }
}
 

Console output (Execution time: 564ms): [Hide/Show]


Top



Edit

Listing 1 : LINQ to SQL and LINQ to XML C# 3.0 Code.

This sample uses LINQ to SQL and LINQ to XML C# 3.0 code to build an RSS file string for Order data. This example is not included in the book.

public void Listing_1_LINQ_RSS_Example()
{
    XDocument doc;
 
    using (NorthwindDataContext db =
        new NorthwindDataContext(connString))
    {
        //db.Log = Console.Out;
 
        // using a LINQ to SQL query, build the RSS items
        var query = db.Orders
                    .OrderByDescending(order => order.OrderDate)
                    .Take(5)
                    .Select(order =>
                        // this LINQ to XML code builds an
                        // item element for every record.
                         new XElement("item",
                             new XElement("title",
                                 string.Format("Order {0} from {1}",
                                    order.OrderID,
                                    order.Customer.ContactName)
                             ),
                             new XElement("description",
                             // build the order detail string
                                 (from detail in order.Order_Details
                                  select detail.Quantity + " x " +
                                  detail.Product.ProductName + ". ")
                             ),
                             new XElement("pubdate",
                                 order.OrderDate ??
                                        DateTime.Now
                                            .ToUniversalTime()
                             ),
                             new XElement("guid",
                                 order.OrderID
                             )
                        )
                    );
 
        // prepare the RSS document header, and add the items
        doc = new XDocument(
 
            // add the header items
            new XDeclaration("1.0", "utf–8", "yes"),
            new XComment("Real–Time Orders RSS Feed"),
            new XElement("rss",
                new XAttribute("version", "2.0"),
                new XElement("channel",
                    new XElement("title", "Orders RSS Title"),
                    new XElement("description", "Recent Orders"),
                    new XElement("link", "http://HookedOnLinq.com"),
                    query)
                )
             );
    }
 
    Console.WriteLine(doc.ToString());
}
 

Console output (Execution time: 112ms): [Hide/Show]


Top



If you would like to comment on this page, click on the Discuss button located on the top-right of each page. Feel free to edit any mistakes or omissions you find. If you have an objection or find in-appropriate content then contact the administrator. This website is not affiliated with Microsoft®, all content and opinions are those of the specific author and some advice, solutions and article may contain unintentional errors - please use care. Powered by ScrewTurn Wiki version 2.0.33. Some of the icons created by FamFamFam.