|
In previous blog entries on LINQ and lambdas, I illustrated the basics of querying in-memory objects using LINQ and how it is all made possible through the use of language extensions and lambda functions. One of the other things that is made possible through LINQ and lambdas is XLinq, an extension to the C# 3.0 language that allows developers to query XML documents in much the same way they can now query database elements and in-memory enumerable objects such as lists and collections.
In addition to being able to query XML documents, you can also generate XML elements on the fly within a LINQ query by creating an instance of the XElement or XAttribute class. In the sample below, I create a complete, fully-functioning RSS feed using a single LINQ query! The data structure from the sample below involves three tables: Articles, Categories, and ArticleCategories. To generate an RSS feed of all of the articles contained in the database, as well as their categories and sort them all by creation date in descending order, all I have to do is use the following LINQ query:
TestDB testDatabase = new TestDB(
"server=localhost; initial catalog=TestDB; integrated security=SSPI;");
XElement rssRoot = new XElement("rss",
new XAttribute("version", "2.0"),
new XElement("channel",
new XElement("title", "My RSS Feed"),
new XElement("link", "http://dotnetaddict.dotnetdevelopersjournal.com"),
new XElement("description", "This is my RSS Feed"),
from article in testDatabase.Articles
orderby article.CreatedOn descending
select new XElement("item",
new XElement("title", article.Title),
new XElement("link", "article.aspx?id="+article.ID.ToString()),
new XElement("description", article.Description),
from articleCategory in article.ArticleCategories
select new XElement("category", articleCategory.Categories.Description)
)
)
);
The TestDB class refers to a class that was generated by absorbing the database schema from the TestDB database and converting that schema into attribute-decorated business objects by the SQLMetal tool that comes with the LINQ preview. The code above produces the following output when there is a single 4-category article contained in the database:
<rss version="2.0">
<channel>
<title>My RSS Feed</title>
<link>http://dotnetaddict.dotnetdevelopersjournal.com</link>
<description>This is my RSS Feed</description>
<item>
<title>New Article</title>
<link>article.aspx?id=1</link>
<description>This is a new article</description>
<category>new</category>
<category>category</category>
<category>sample</category>
<category>test</category>
</item>
</channel>
</rss>
At this point there's very little left to say. Granted, creating an RSS feed isn't the most difficult of tasks, but it typically involves painstaking and tedious DOM manipulation or the creation of a separate tool class that encapsulates the manipulation of RSS-specific XML elements. The fact that you can blend the query to retrieve the data that will be in the RSS feed with the code that generates the RSS XML itself is extremely powerful, and applies to far more tasks than just RSS generation.
If you think of the number of times in the past year or two that you've had to read data and build an XML hierarchy from that data (and you didn't cheat and use SQL 2005's XQuery support), then you can probably picture how much time this little technique would have saved you.