Personally I find that LINQ to SQL + LINQ to XML works really nicely, so long as the result is small enough to fit in memory comfortably (i.e. it's not as good for a streaming solution).
For instance, I have a single (very large) statement which converts items in my database into an RSS feed. It's basically a declarative approach, and it works well. It's something like this:
XDocument doc = new XDocument(
new XDeclaration("1.0", "UTF-8", "yes"),
new XElement("rss",
new XAttribute("version", "2.0"),
new XElement("channel",
new { title="C# in Depth news",
link ="http://csharpindepth.com/News.aspx",
description = "C# in Depth news items",
language = "en-gb",
generator = "LINQ",
docs = "http://blogs.law.harvard.edu/tech/rss",
pubDate = DateTimeOffset.UtcNow.ToString
(Rfc822Format, CultureInfo.InvariantCulture),
lastBuiltDate = items.First().CreatedDate.ToString
(Rfc822Format, CultureInfo.InvariantCulture),
}.AsXElements(),
items.Select(item =>
new XElement("item",
new { title=item.Title,
link=string.Format(LinkFormat, item.NewsItemID),
description=item.Summary,
author="[email protected]",
pubDate = item.CreatedDate.ToString
(Rfc822Format, CultureInfo.InvariantCulture)
}.AsXElements()
)
)
)
)
);
That uses a little extension method I've got to convert anonymous types into XElements - it's available in MiscUtil, and does the obvious thing.
(And yes, I should probably have a method to convert dates to Rfc822 format...)