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]
State: AK
Adam Gauwain
State: CA
Jeffery Deane
Barney Gottshall
State: FL
Collin Zeeman
State: OR
Ariel Hazelgrove
State: TX
Mack Kamph
Blaine Reifsteck
State: WA
Stewart Kagel
Chance Lard
Armando Valdes
Top
EditCreating Summary XML for Data
EditListing 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]
<!––Summarized Incoming Call Stats––>
<contacts>
<contact>
<lastName>Gottshall</lastName>
<firstName>Barney</firstName>
<count>4</count>
<totalDuration>31</totalDuration>
<averageDuration>7.75</averageDuration>
</contact>
<contact>
<lastName>Hazelgrove</lastName>
<firstName>Ariel</firstName>
<count>2</count>
<totalDuration>27</totalDuration>
<averageDuration>13.5</averageDuration>
</contact>
<contact>
<lastName>Kagel</lastName>
<firstName>Stewart</firstName>
<count>2</count>
<totalDuration>13</totalDuration>
<averageDuration>6.5</averageDuration>
</contact>
<contact>
<lastName>Kamph</lastName>
<firstName>Mack</firstName>
<count>2</count>
<totalDuration>44</totalDuration>
<averageDuration>22</averageDuration>
</contact>
<contact>
<lastName>Lard</lastName>
<firstName>Chance</firstName>
<count>2</count>
<totalDuration>22</totalDuration>
<averageDuration>11</averageDuration>
</contact>
<contact>
<lastName>Valdes</lastName>
<firstName>Armando</firstName>
<count>2</count>
<totalDuration>20</totalDuration>
<averageDuration>10</averageDuration>
</contact>
</contacts>
Top
EditListing 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]
<!––Summarized Incoming Call Stats––>
<contacts>
<contact>
<lastName>Gottshall</lastName>
<firstName>Barney</firstName>
<count>4</count>
<totalDuration>31</totalDuration>
<averageDuration>7.75</averageDuration>
</contact>
<contact>
<lastName>Hazelgrove</lastName>
<firstName>Ariel</firstName>
<count>2</count>
<totalDuration>27</totalDuration>
<averageDuration>13.5</averageDuration>
</contact>
<contact>
<lastName>Kagel</lastName>
<firstName>Stewart</firstName>
<count>2</count>
<totalDuration>13</totalDuration>
<averageDuration>6.5</averageDuration>
</contact>
<contact>
<lastName>Kamph</lastName>
<firstName>Mack</firstName>
<count>2</count>
<totalDuration>44</totalDuration>
<averageDuration>22</averageDuration>
</contact>
<contact>
<lastName>Lard</lastName>
<firstName>Chance</firstName>
<count>2</count>
<totalDuration>22</totalDuration>
<averageDuration>11</averageDuration>
</contact>
<contact>
<lastName>Valdes</lastName>
<firstName>Armando</firstName>
<count>2</count>
<totalDuration>20</totalDuration>
<averageDuration>10</averageDuration>
</contact>
</contacts>
Top
EditCreating an RSS Feed of Order Data from SQL Server
EditListing 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
EditListing 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