Friday, March 16, 2007

"LINQ 2.0" in Early Returns from QCon 2007, London

LINQ 1.0 hasn't hit RTM and "LINQ Creator" Erik Meijer is talking about LINQ 2.0 already.

Tim Anderson blogs from the QCon 2007 conference held in London this week about Erik's "Democratizing the Cloud" keynote:

LINQ 2.0 is about simplifying multi-tier, cross-platform web applications—hence the title of the talk, “Democratizing the cloud.”

So how do we do that? The starting point is that users want the same experience everywhere, irrespective of computer platform or device. Meijer’s idea is programmers should be able to code for the easiest case, which is an application running directly on the client, and being able to transmute it into a cross-platform, multi-tier application with very little change to the code.

Read Tim's eloquent review of Erik's keynote presentation.

Stefan Tilkov of InnoQ covered Erik's "Introduction to Microsoft Language Integrated Query (LINQ)" sales pitch technical presentation. His conclusion:

Overall: great talk, great guy, way too little time.

Final quote: Programming Language Theory is relevant. But it requires at least 20 years of patience and ripening.

Read Stafan's rough notes.

Note: QCon is a JAOO (Denmark) and InnoQ (Germany and Switzerland) conference.

Other luminaries presenting at QCon 2007 are Martin Fowler, Ted Neward, Christian Weyer, Cameron Purdy, Cedric Beust, Kevlin Henney, Zed Shaw, and Dave Thomas.

Stefan says:

I also managed to interview all of the speakers for InfoQ (except for the one with Paul Downey, which I plan to do tomorrow), and all of the presentations have been videotaped, too — a lot of excellent content to look forward to. [Emphasis added]

I'll update this post with links to LINQ-related content as they appear.

Update 3/17/2007: Sadek Drobi covered Erik's keynote with photos and stream-of-conciousness quotations. Fellow Netherlander Samuel Renzato says about Erik's LINQ talk: "All in all, a very riveting presentation." (Samuel, like many other folks (including me) is reading Jimmy Nilsson's Applying Domain-Driven Design and Patterns: With Examples in C# and .NET.

Update 3/23/2007: InfoQ (not to be confused with InnoQ) has a blogger's summary of the entire conference. This link points to Erik's presentation.

Technorati tags: , , , ,

Wednesday, March 14, 2007

Persistence Ignorance Is Bliss, but Is It Missing from the Entity Framework?

A brief item that appeared yesterday afternoon in Danny Simmons's system.data.objects dev guy blog led me to the March 13, 2007 "Persistence Ignorance in the Entity Framework" post by Chris Moore (a.k.a. NTDeveloper) in the ADO.NET Orcas forum. The post is a copy of a March 8, 2007 comment to Shyam Pather's "Using Stored Procedures for Change Processing in the ADO.NET Entity Framework" post in the ADO.NET Team blog.

One of the primary features of object/relational mapping (O/RM) tools, such as the Entity Framework, is persisting domain object (entity) instances as rows in relational database tables. Jimmy Nilsson*, the author of Applying Domain-Driven Design and Patterns: With Examples in C# and .NET, defines the term persistence ignorance (PI) as a property of "ordinary classes where you focus on the business problem at hand without adding stuff for infrastructure-related reasons. ... The classes should focus on the business problem at hand. Nothing else should be in the classes in the Domain Model."

Chapter 6, "Preparing for Infrastructure," of Nilsson's book states on page 184:

[I]f you use a PI-based approach for persistent objects, there’s no requirement to do any of the following:

    • Inherit from a certain base class (besides object)
    • Only instantiate via a provided factory
    • Use specially provided datatypes, such as for collections
    • Implement a specific interface
    • Provide specific constructors
    • Provide mandatory specific fields
    • Avoid certain constructs
    • [W]rite database code, such as calls to stored procedures

The preceding language implies that requiring any of the above elements prevents implementing an object persistence layer that qualifies as persistence ignorant.

Chris takes the following issues with the ADO.NET 3.0 Entity Framework's implementation in the Orcas March 2007 CTP:

  1. Entities must subclass the Entity framework class, and
  2. It is necessary to attach various attributes to entity properties.

Both of which violate Nilsson's PI principles.

Kevin Hoffman, who has compared the August 2006 CTP of the .NET Entity Framework with Ruby on Rails' ActiveRecord, adds his PI objections in this shortened entry:

Getting us "partly there" seems to be a big theme in the Entity Framework. Virtually all of the features that I like about the EF are about 75% of what I want them to be. One such feature is Persistence Ignorance. In a true entity model, I should, in theory, be able to take the model of my entities, complete with ability to create a runtime graph of that model - and go and load data from 3 different stores (XML, Access, or SQL Server) and not change a single line of code. [Emphasis added.]

Microsoft describes the Entity Framework/Entity Data Model as an OR/M—not a domain model management (DMM)—tool, so expecting the capability to substitute an arbitrary XML storage schema for a relational schema is asking a bit much, in my opinion. (Typed DataSets handle persistence to XML files reasonably well, although not in the same way as an O/RM tool.) Substituting Access, Oracle or DB2 for SQL Server would require specifying the appropriate OLE DB provider by changing connection strings. In this case, you'd lose the performance advantages of .NET managed providers for all but Access (Jet) databases. However, it's unlikely that anyone would use compatibility with Jet databases as a criterion for choosing an OR/M tool.

According to Danny Simmons' forum answer to Chris and Kevin's post (abridged):

    1. The requirement that entity classes inherit from a single base class: This is a restriction we are actively working on removing, and in a future CTP you will be able to create your own data classes which do not inherit from one of our framework classes but instead just implement a set of interfaces that define the minimal functionality required for successful interaction with the framework.
    2. The requirement to attach attributes to properties on your entity objects: The long-term idea is to have two separate opportunities for abstraction: First, there is the mapping provided by EntityClient which separates your conceptual model from the store format. The second abstraction opportunity is between the data classes (your objects) and the conceptual schema. For Orcas we have scoped the problem down and require that the mapping at this layer be 1-to-1.

It is true that we don't allow complete persistence ignorance in that we don't support true, plain-old-CLR objects [POCO] with absolutely no knowledge of persistence--you have to expose to the framework which properties and classes actually need [to be] persisted.

Jimmy addresses the issues of .NET attributes in a note on page 188:

Something that has been discussed a lot is whether .NET attributes are a good or bad thing regarding decorating the Domain Model with information about how to persist the Domain Model.

My opinion is that such attributes can be a good thing and that they don’t really decrease the PI level if they are seen as default information that can be overridden. I think the main problem is if they get too verbose to distract the reader of the code.

Danny says in his 3/13/2007 blog post:

Unfortunately I don't have the time right now to write up a full treatment of this subject, but it's important, and it just came up in the Orcas ADO.Net forum. I took a quick stab at it in a response to a question there, and I don't want to lose track of this idea for future treatment.

and in a 3/15/2007 forum post:

It's my intention to try to write up a fairly detailed response because this is such an important topic. Unfortunately I'm driving hard toward a deadline right now so this is going to have to be delayed a few days. I just wanted to let you know that I haven't forgotten, and I will respond.

I'm looking forward to Danny's "future treatment" as well as commentary by .NET O/RM competitors: Frans Bouma (LLBLGen Pro), JBoss/Redhat (NHibernate), Mats Helander (NPersist), Paul Wilson (WilsonORMapper) and others.

Note: Paul offers downloads of his LINQ and O/R Mapping presentation and introductory ORMapper and NHibernate examples.

Major Update 3/16/2007: Sam Gentile's ADO.NET 3 - Entity Framework without Persistance Ignorance post quotes Ayende Rahien's post of almost the same name that take's Microsoft's ADO.NET Team to task for ignoring (or failing to fully support) Persistance Ignorance. (Be sure to read the comments, especially about designers and generated code.) Sam says that he and and his cohorts (Jeremy Miller, Scott Bellware, Jeffery Palermo, raymond lewallen, Jean Paul Boodhoo and James Kovacs) plan to teach the team about NHibernate at the Most Valuable Professional (MVP) global conference (Microsoft 2007 MVP Global Summit) this week.

Jeffrey Palermo (C# MVP) says in his Linq to Entities: Microsoft's first go at O/R Mapping (they need our feedback now!) - level 300 post:

I have email addresses for several people on the team, and I'll be letting them know what is so compelling about NHibernate and why the above issues have to be resolved before RTM and not after. ...

I want Linq to Entities to succeed. I want frameworks and tools to continually get better; therefore, I will be communicating with the product team to voice my strong concerns over the current direction.

Of course Entity Framework/LINQ to Entities isn't "Microsoft's first go at O/R Mapping." That was ObjectSpaces, which died in the Whidbey (VS 2005 beta) era. Click here for previous OakLeaf posts obout the rise and fall of ObjectSpaces and see, especially, The Language Integrated Query (LINQ) Project (September 2005).

In a 3/16/2007 comment to his LINQ to Entities post, Jeffry says:

I don't think there is any documentation yet, just the bits. I spoke with the Entity Framework architects today, and the roadmap is actually quite bright, so I'm less concerned now. I think they are on the right track, but it will take a while, so don't expect to have your domain-centric O/R mapper in Orcas. I'm not sure what I can disclose, but I'll find out and blog an update.

You can watch Channel9's "ARCast - NHibernate" segment with NHibernate expert Ben Day. Ben will present "Building ASP.NET Database Applications with NHibernate" at 1005 Media's VSLive San Francisco and VSLive Orlando.

Jeff Perrin weighs in with a Persistence Ignorance post and a link to an 2005 O/R Mapping: Attributes vs. XML For Mapping entry that connects to Steve Eichart's If Attributes are good enough for Indigo why aren't they good enough for O/R Mappers? post. Steve discusses the [DataContract] attribute that Indigo (WCF) now shares with ADOEF and Chris Moore wants removed or made optional. According to Danny, they are present to help automate WCF serialization and are optional.

Update 3/16/2007: Minor edits and a brief addition.

Note: Mats' Attributes In NPersist post describes a new NPersist feature that enables substituting attributes for metadata in ObjectMapper's XML files. NHibernateEg provides a method for substituting .NET attributes for NHibernate's .hbm.xml files.

* Jimmy Nilsson is a widely respected .NET and database developer with 20 years of experience. He owns and runs the Swedish consulting company JNSystemKonsult AB. In addition to Applying Domain-Driven Design and Patterns: With Examples in C# and .NET, he wrote .NET Enterprise Design with Visual Basic .NET and SQL Server 2000 in 2001. He's also written numerous technical articles and is a well-known trainer and conference speaker. His "current pet project is called NWorkspace and is (or, at least, might become) what I call adapters for different persistence solutions. Nope, it's not another OR Mapper for .NET, which might come as a shock! Instead, what NWorkspace does is try to reuse the functionality of the current OR Mappers." He now says that LINQ is a better NWorkspace—"I quite often receive enquiries about when I'm going to publish NWorkspace, but I'm still hesitant to do so as it's definitely not of publishable quality. Yet it occurred to me that to a great extent LINQ is largely what the vision of the querying part of NWorkspace was all about. Of course LINQ is way, way better and way more complete. "

Update 3/28/2007: Danny Simmons says there will be A delay before I write more about persistence ignorance... so he can more carefully consider his reply. Danny also posted Change Tracking Mechanisms for the Entity Framework, which covers alternative approaches to change tracking, which is based on values designated "concurrency tokens."

C# MVP Scott Bellware contributes Entity Framework Challenges, an essay arguing against the data-centricity of the current Entity Framework design:

When I work with the Entity Framework I feel trapped in a data guy's perspective of what a framework for behavioral business objects should be.

An entity from the perspective of a data guy is a chunk of data; something that is loosely akin to a row in a table or a row in a view (although that's a bit of an over-simplification). To an application programmer working with entity-centric code, an Entity is a chunk of behavior that can also hold on to its data. ...

The Entity Framework must undergo significant change before it no longer presents impediments to behavior-driven development practices for behavior-centric objects. The framework is an important step forward for the Microsoft data access strategy, but it's only a baby step forward in terms of the frameworks, practices, and expectations that Microsoft customers already have. ...

I'm still committed to the Entity Framework, but it's frustrating to have to turn back the clock on some of the more effective practices that my team has for ensuring success with application-level entity programming. I hope that more interaction between the Entity Framework team will bring about a framework that allows for and even enhances contemporary application development practices in .NET.

I wonder if Scott will remain that committed to the Entity Framework if the EDM Designer doesn't arrive by Orcas RTM.

Another C# MVP, John Papa, argues in Entity Framework Thoughts:

In its current state the Entity Framework can be generated from an existing data model (or can be created by hand with XML). The data team at Microsoft knows this is a limitation and is working on solutions to make building and tweaking entities, mapping the conceptual model to a logical model, and overall design of the EDM much more fluid. I am very excited about seeing what they produce on this end.

Be sure to read the flurry of comments that ensued.

Here's an early (9/13/2006) ADO.NET Team post by Atul Adya that explains Entity Mapping in ADO.NET vNext in considerable detail and discusses the View Generator (a.k.a. Mapping Compiler), Mapping Views, and Query Mapping (QM) views, which refers to an earlier Queries in ADO.NET vNext post by S. Muralidhar (Murali).

The Last Word (4/24/2007) on the Entity Framework discussion at the MVP Summit by Jeremy D. Miller: LINQ for Entities is NOT the O/R Mapper I want today, but might be if and when they... is the best and most reasoned exposition of the current issues developers have with LINQ to Entities and the Entity Framework: "[T]he intrusiveness of Linq for Entities into your Domain Model classes, the general clumsiness of the configuration model as it is right now, and the mechanisms for tracking object state." Be sure to read the comments and then check out Scott Bellware's On Being the "NHibernate Mafia" post.

Tuesday, March 13, 2007

Yet Another Primer on New Language Features in Orcas

Microsoft's Scott Guthrie has joined the choir of bloggers* serializing items about the new language features implemented by Visual Studio vNext, a.k.a., Orcas. Most articles in these series are devoted entirely to C# 3.0, some give a nod to VB 9.0 here and there, and a very few cover VB 9.0 only. An obvious inference is that LINQ afficianados are inclined to (re)iterate IEnumerable<linqPost> rather than IEnumerable(Of LINQPost).

Scott introduces his series with this description [emphasis added]:

In addition to all the great new framework and tool features, one of the things that I think developers (of all .NET application types) will really love about Orcas are some of the new language features and improvements that are coming to both VB and C#. These language changes are going to improve our development experience in both subtle and dramatic ways, and will really improve productivity and reduce the amount of code we need to type.

Over the next few weeks I'm going to try and blog about several of these language improvements, and show how they can be used together to produce some really powerful results.

Following are links to the complete set of Scott's posts (Updated May 15, 2007):

There's an earlier item about Scott's May 2006 Using LINQ with ASP.NET (Part 1) post and a followup article, Using DLINQ with ASP.NET (Part 2). Both parts are C#-only.

One of the issues I plan to explore in the next few months is whether reducing "the amount of code we need to type" improves programmer productivity and the extent to which it affects the cost to maintain code over the application lifecycle. LINQ's enhanced query syntax clearly requires more keystrokes than using C# lambda expressions; the forthcoming VB lambda syntax will be more verbose. Obviously, VB's With ... End With construct, which isn't available in C#, is a dramatic time and keystroke saver, as is the shorthand declaration, Dim objVar as New WhateverType for C#'s whateverType objVar = new whateverType. However, if the number of keystrokes required to achieve the desired result is the criterion of language efficiency, we'd all be writing APL.NET.

*Links to Other Series on New Orcas Language Features and LINQ

Microsoft added most new Orcas language features to support LINQ. Thus the majority of serial expositions of new C# 3.0 or VB 9.0 syntax include references to or examples of one or more LINQ flavors. Here are links to recent OakLeaf items that describe other LINQ/language-related series:

Mike Dodaro's series qualifies only because future items might cover LINQ to Entities.

Following are some series (or equivalents) that don't have their own OakLeaf posts:

Update 5/29/2007: Scott Guthrie started another LINQ series on , this time covering LINQ to SQL:

This series adds VB examples to Scott's traditional C# sample code. (Thanks, Scott.) I'll add later members of the series as they appear.

Update 6/6/2007: UK developer Granville Barnett delivers this series (each of which includes a substantial amount of C# code) on the DotNetSlackers site:

Hooked on LINQ (C#) by Troy Magennis is a wiki, not a blog, but it contains more than 100 pages of C# code examples.

Kevin Hoffman's .NET Addict's Blog (C#) has several posts on LINQ topics, including a Dr. Dobbs article, "LINQ to Web 2.0," and LINQ to XAML and LINQ to SharePoint examples.

Andrew Matthews appears to have a "How LINQ Works" series in the making:

are among his several posts on C# and LINQ topics.

Alex Thissen was one of the early authors of a blog series on C# 3.0:

  1. C# 3.0 for mere mortals, part 1: Extension methods (3/26/2006)
  2. C# 3.0 for mere mortals, part 2: Implicit typing (3/28/2006)
  3. C# 3.0 for mere mortals, part 3: Anonymous types (6/14/2006)
  4. C# 3.0 for mere mortals, part 4: Object and collection initializers (7/16/2006)
  5. C# 3.0 for mere mortals, part 5: Lambda expressions (11/7/2006)
  6. C# 3.0 for mere mortals, part 6: Expression trees (missing)
  7. C# 3.0 for mere mortals, part 7: Query expressions (missing)

In part 5, Alex described his unfinished opus as "the longest running series on C# 3.0."

Microsoft UK evangelist Daniel Moth's posts aren't members of a formal series, but he suggests reading them in order:

  1. LINQ
  2. Local Variable Type Inference (and the VB version)
  3. Object Initiliasers
  4. Anonymous Types
  5. Extension Methods
  6. Lambda Expressions (and the VB version)
  7. Decomposing LINQ (includes Query Expressions)

It's encouraging to see at least some VB coverage in language-oriented posts. Daniel's "Language Enhancements and LINQ" slides for Microsoft UK's Technical Roadshow 2007 (in .pptx format) also include a smattering of VB.

Update 4/9/2007: Earlier C# 3.0 and LINQ Series

Several C# 3.0 and LINQ series originated from the LINQ May 2006 CTP. For the sake of completeness, following are some representative examples:

Sahil Malik's seven-part "Demystifying C# 3.0" sequence consists of brief ("five-minute") examples of the following C# 3.0 concepts:

  1. Demystifying C# 3.0 - Part 1: Implicitly Typed Local Variables "var"
  2. Demystifying C# 3.0 - Part 2: Anonymous Types
  3. Demystifying C# 3.0 - Part 3: Extension Methods
  4. Demystifying C# 3.0 - Part 4: Lambda Expressions
  5. Demystifying C# 3.0 - Part 5: Object and Collection Initializers
  6. Demystifying C# 3.0 - Part 6: (LINQ) Query Expression Translation (to C# 3.0)
  7. Demystifying C# 3.0 - Part 6: Expression Trees

Sahil extended his "Demystifying" approach to LINQ to SQL (then DLinq) with:

  1. An Introduction to DLinq
  2. Setting Up a DataContext Class
  3. Querying for Data using DLinq
  4. Stored Procedure and UDF support in DLinq
  5. Stored Procedures that return a Definite Shape with DLinq
  6. Stored Procedures that return a Variable Shape with DLinq
  7. DLinq: Submitting your Changes

Bill Wagner delivered the following posts about DLinq's technique for translating LINQ queries to T-SQL statements and other related topics:

  1. LINQ to SQL Introduction
  2. LINQToSQL: Translating C# to SQL
  3. LINQ For SQL Queries: Where Clauses and Database Queries
  4. LINQ for SQL Queries: Mathematics Functions
  5. LinqToSql: Joins (9/13/2006)
  6. Linq2SQL: Group By Order By, and why I prefer C# To T-SQL (9/28/2006)
  7. LINQ 2 SQL Set Operations (10/6/2006)
  8. Paging output with Linq2SQL (10/14/2006)
  9. First Commentary on LINQ vs. Python (10/17/2006)
  10. Updating Database Content using Linq2SQL (11/1/2006)
  11. LINQ to SQL: Optimistic ConcurrencyL (12/4/2006)
  12. More LINQ 2 SQL: Object Identity and Nullable Queries (2/26/2007)

Note: The two preceding lists (except Bill Wagner's dated posts) are from Scott Guthrie's Understanding LINQ to SQL Query Translations post of September 1, 2006.

Update 4/12/2007: Eric White's Query Composition using Functional Programming Techniques in C# 3.0 is an October 2006 tutorial about taking the FP approach to writing LINQ queries that's based on the LINQ May 2006 CTP. Eric says:

It is certainly possible to write simple LINQ queries without using these techniques, but as soon as you start writing more complicated queries, you need to understand these techniques.

Eric explains query expressions, lambda expressions, extension methods, local variable type inference, object and collection initializers, tuples and anonymous types, the yield keyword, lazy evaluation, and aggregation more eloquently and in more detail than most other authors.

Update 3/19/2007: Mike Taulty's Deconstructing LINQ item offers an all-in-one-post series of 10 brief elements with "codelets" that demonstrate most new C# 3.0 language features. Mike is a Microsoft UK evangelist "involved in getting information out to developers about what's happening with the Microsoft platform through online mechanisms like newsletters, blogs, videos and through offline mechanisms such as technical sessions."

If you know of any more LINQ-based series in the making, especially posts that provide VB 9.0 code samples, please leave a comment.

Monday, March 12, 2007

Updated LINQ SampleQueries and New LINQ to XML in VB Video

Charlie Calvert has posted a further update to the March 5, 2007 version of the C# SampleQueries for the VS Orcas March 2007 CTP. The new update, which you can download here or from Charlie's blog, includes about 101 LINQ to Entities queries, which were missing from the earlier update.

According to Charlie, the latest update contains:

  • LINQ to Objects
  • LINQ to SQL
  • LINQ to XML
  • LINQ to XML Part II
  • LINQ to DataSet
  • LINQ to Entities

Andrew Conrad (of ObjectSpaces fame) notes that Erick Thompson posted on March 6, 2007 workarounds for the first set of updates.

Paul Vick provides a heads up for a new Channel9 video about VB 9.0's LINQ to XML features for Orcas. The 12:47 "LINQ to XML API and VB 9.0" segment shows lead developer David Schach's VB 9.0 application that creates a weekly RSS feed for new photographs on his Web site. Hopefully, VB's LINQ for XML API can be used for something other than RSS feeds.

Slightly Off-Topic

Scott Wisniewski, a developer on the VB 9 Compiler Team has posted the sixth a series of articles on the new extension methods included in Visual Basic 9.0's "Orcas" release: Extension Methods Best Practices.

The first installment of Granville Barnett's "Introducing LINQ" series appeared today on dotnetslackers.com. Granville says the article covers:

  • Querying of in-memory collections
  • A subset of the standard query operators
  • Compiler generated code including a discussion on "under the covers" compiler behaviour like cached anonymous delegates and delegates
  • Lambda Expressions

Friday, March 09, 2007

LINQ's Missing ToDataTable Method Saga

Several LINQ pilgrims, including Julie Lerman, the authors of three books about LINQ (two published and one in process), Mike Taulty and I, have been attempting to find the IEnumerable<T>.ToDataTable and DataTable.LoadSequence methods in the Orcas March 2007 CTP's LINQ implementation.

Here's the answer from ADO.NET program manager Erick Thompson, author of the LINQ to DataSet documentation series, in the LINQ Project General Forum:

We decided to remove the ToDataTable for any sequence, as there isn't a correct way to always load data from a sequence into a DataTable. For example, what do you do with a sequence of Type A where some instances are also Type B, where B inherits from A? Do you extend the DataTable schema to allow for the additional fields in B? Throw an error? Not load the additional data?

We are looking at bringing this functionality back at some point. What would be helpful is a better understanding of what you would like to use it for. What LINQ to XXX queries do you want to load into a DataTable, and why?

My immediate reaction was that there would be few, if any, System.Data namespace members were such "always" restrictions applied to them.

Fabrice Marguerie's reply makes the most sense to me:

I would expect the behavior to be basic. I think that most of the time when we work with DataSets, we do not use mixed data types. Often the data will come from LINQ to SQL or LINQ to XML queries that return only of type of data as specified in their select clause.

I would bring back the ToDataTable and LoadSequence operators back to life, even if they throw exceptions in unsupported cases. These cases would be the minority, I think. Of these cases should be documented. It probably require more thought, but having ToDataTable use only the members of the base type (the generic type T of the sequence) can be an acceptable limitation, I think.

One issue is that operating on a non-homogeneous type would appear to throw runtime not compile-time, exceptions. A major objective of LINQ is to substitute compile-time for runtime exceptions.

Update 4/4/2007: Julie Lerman points to Fabio Claudio Ferracchiati's May 2006 to March 2007 comparison list post of March 7, 2007, that lists the differences between the two CTPs' LINQ implementation. Fabio is the author of LINQ for Visual C# 2005 and LINQ for VB 2005 books mentioned the first paragraph of this post. Fabio also has posted updated code for the C# title. You can buy either title as a downloadable eBook from Apress.

LINQ to XML Bridge Classes to System.Xml

The XML Team posted on March 3, 2007 a more detailed description of the LINQ to XML bridge classes to System.Xml. This post includes simple C#-only (of course) code samples for XPath, XSLT, and XSD validation.

The team's February 2, 2007 XML Features in the February CTP of Visual Studio “Orcas” post described the Bridge Classes as follows:

These implementations of System.Xml interfaces such as XmlReader, XmlWriter, and XPathNavigator will allow XPath / XSLT to be used over LINQ to XML trees, allow XSLT transformations to produce an LINQ to XML tree, and allow efficient data interchange between DOM and LINQ to XML applications. There is also a Validate extension method to validate an XElement tree against an XML Schema.

The new post explains the objective of the bridge classes more concisely:

[T]he whole point of the bridge classes [is] to mix-n-match LINQ to XML objects (which we hope are easier to use than XmlDocument objects, and can easily integrate with other LINQ providers) with existing code.

Again, it would be nice to see some VB 9.0 samples from the XML team.

Streaming with LINQ to XML Series

The XML Team has started a multipart blog series on the topic of Streaming with LINQ to XML and the XStreamingElement class. The objective of streaming is to enable forward-only processing of a large input or output data source, such as log files or serialized relational data, in order to avoid loading an entire document into memory. The The XmlDataReader and XmlDataWriter pull parsers currently provide the .NET Framework's streaming implementation.

Streaming with LINQ to XML - Part I describes the XML Team's efforts to develop a streaming API for LINQ to XML:

The LINQ to XML design team has spent a lot of effort over the last year or so wrestling with alternative ways to provide streaming functionality in a way that is consistent with the API's overall philosophy. The May 2006 CTP included support for streaming output (but not input) via an XStreamingElement class that essentially allowed XML-like trees of IEnumerable<T> instances that could be lazily consumed while being saved as XML text. This was removed from later CTPs to "keep the slate clean" while incompatible options were considered.

Following is the (abridged) outcome of the team's design deliberations:

After literally months of discussion and prototyping, we decided to address these requirements by a) putting XStreamingElement back in the supported API as it was in the May CTP; b) to NOT push any streaming input API into Orcas RTM, but to release one or more implementations of the ideas we’ve discussed as code samples that can be implemented on top of the public API.

We'll present some pretty straightforward code to handle the most basic use cases such as huge logfiles with a very flat XML structure. Maybe some of these examples can migrate into a "LINQ to XML Power Tools" library of some sort (hint, hint, MVPSs?). Anyway, stay tuned for the details, and please let us know what works for you and what you still need to work with XML easily and efficiently.

Let's hope future code samples include VB 9.0 for a change.

Streaming with LINQ to XML - Part 2 delivers the "code to handle the most basic use cases such as huge logfiles with a very flat XML structure." The team's approach, using a 10-MB Wikipedia abstract.xml file for the example, is:

The key is to write a custom axis method that functions much like the built-in axes such as Elements(), Attributes(), etc. but operates over a specific type of XML data. An axis method typically returns a collection such as IEnumerable. In the example here, we read over the stream with the XmlReader's ReadFrom method, and return the collection by using yield return. This provides the deferred execution semantics necessary to make the custom axis method work well with huge data sources, but allows the application program to use ordinary LINQ to XML classes and methods to filter and transform the results.

(Still no VB code examples.)

Update: 3/25/2007: Added link to part 2, abstract and complaint.

Note: Ralf Lämmel, the "father of LINQ to XSD," is a LINQ to XML streaming enthusiast. (LINQ to XSD is a product of Erik Meijer's Tesla incubator group that's in the early preview stage.) The article cites his "API-based XML Streaming with FLWOR Power and Functional Updates" paper presented at XML 2006.

Thursday, March 08, 2007

VS 2005 SP1 Update for Windows Vista Released

Microsoft has released an updated version of Visual Studio 2005 Service Pack 1 for all Visual Studio 2005 editions. The Release Notes for VS80sp1-KB932232-X86-ENU.exe are here. The updated SP1 replaces the update's Beta version, Hotfix for Visual Studio 2005 SKU name - ENU (KB929470).

According to S. “Soma” Somasegar, Microsoft's corporate vice president of the Developer Division:

"We fixed a number of significant issues around debugging and profiling, and around creating ASP.NET applications for IIS on the developer machine. We also wanted to improve the feedback that Visual Studio gives to developers when an error occurs on Windows Vista.

Caution: Be sure to remove the Beta version before installing the RTM version of the update.

I downloaded and installed the RTM update. I was surprised that installation required several minutes on fast machines, including a few minutes with "Time remaining: 0 seconds" in the installation message box. I ran some quick checks on recent SQL Server 2005 Compact Edition (SSCE), LINQ, and Entity Framework projects and didn't observe any untoward behavior.

Wednesday, March 07, 2007

Critical Update for SQL Server 2005 SP2

Microsoft has issued a critical update for SQL Server 2005 SP2 Workgroup edition and higher. The update does not apply to SQL Server 2005 Express Edition (SSX).

According to Knowledge Base article 933508, Microsoft SQL Server 2005 Service Pack 2 issue: Cleanup tasks run at different intervals than intended:

If you apply the initial release version of Microsoft SQL Server 2005 Service Pack 2 (SP2), existing SQL Server 2005 maintenance plans and Integration Services packages that contain cleanup tasks run those tasks at shorter intervals. The issue occurs only if all the following conditions are true:

  • You downloaded SQL Server 2005 SP2 before March 05, 2007, and installed that download package.
  • You use SQL Server 2005 maintenance plans or Integration Services packages.
  • Those plans or packages include History Cleanup tasks or Maintenance Cleanup tasks.

The resolution for this issue is described in the "Resolution" section.

Users of SQL Server 2000 legacy maintenance plans and users who downloaded SP2 after March 05, 2007 are not affected. On this date, SQL Server 2005 SP2 was refreshed to include an update that avoids this issue.

Note This problem only affects the main SQL Server 2005 SP2 packages. These packages use the following naming convention:

SQLServer2005SP2-KB921896-ProccessorType-Language.exe

This problem does not affect SQL Server 2005 Express Edition or SQL Server 2005 Feature Pack packages.

Tuesday, March 06, 2007

Orcas March CTP on Vista Database Connections Problem Solved

An anonymous commenter provided the solution to the connection string problem I reported in my March 04, 2007 Orcas March 2007 CTP Installation Problems post: If you set up the Self-Extracting Install version of the Orcas March 2007 CTP on Windows Vista without installing SQL Server 2005 Express, you can't persist Data Connections in Server Explorer. Installing SQL Server 2005 [Express] under any current Windows OS breaks the Project Designer's Properties page and the Workflow Designer. Update 4/25/2007: This fix does not apply to Orcas Beta 1, which doesn't exhibit the preceding problems. See SQL Server Compact Edition FAILS to connect in Server Explorer with Beta 1 in the ADO.NET Orcas forum. Update 3/7/2007: Windows Vista isn't the culprit. "Anonymous" says that the connection string problem also occurs with—and the solution works for—Windows XP SP2. My installation on Windows Server 2003 R2 SP1 under Virtual Server 2005 R2 SP1 Beta 2 didn't have the problem. Inspecting that machine.config file shows that the offending line commented out below wasn't present. I believe I omitted Orcas support for devices from that install. I'll run another test with Windows XP SP2 as the guest OS later this week to confirm. Here's the full text of the comment:

The issue with SQL Connection strings is much larger than what you elude to. It also breaks almost all visual database design tools in Orcas, SQL Server Management Studio and Visual Studio 2005. This includes the table designer, database diagrammer and the view designer.

I have good news though. There is a fix. If you open up the machine.config file you will notice multiple entries for the SQL CE stuff in the system.data section. Comment these out (this will break SQL CE, which is fine for most people) and your SQL Server editing will return. I believe if you comment out 2 of the 3 leaving the version 9 dll intact the SQL CE stuff will remain working.

The commenter is correct. To enable persisting Data Connections in Server Explorer under Windows Vista comment out the line shown in bold from \Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG\machine[.config]:
<system.data>
  <DbProviderFactories>
    <add name="Odbc Data Provider" invariant="System.Data.Odbc" description=".Net Framework Data Provider for Odbc" type="System.Data.Odbc.OdbcFactory, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    <add name="OleDb Data Provider" invariant="System.Data.OleDb" description=".Net Framework Data Provider for OleDb" type="System.Data.OleDb.OleDbFactory, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    <add name="OracleClient Data Provider" invariant="System.Data.OracleClient" description=".Net Framework Data Provider for Oracle" type="System.Data.OracleClient.OracleClientFactory, System.Data.OracleClient, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    <add name="SqlClient Data Provider" invariant="System.Data.SqlClient" description=".Net Framework Data Provider for SqlServer" type="System.Data.SqlClient.SqlClientFactory, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    <!-- <add name="SQL Server CE Data Provider" invariant="Microsoft.SqlServerCe.Client" description=".NET Framework Data Provider for Microsoft SQL Server 2005 Everywhere Edition" type="Microsoft.SqlServerCe.Client.SqlCeClientFactory, Microsoft.SqlServerCe.Client, Version=9.0.242.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" /> -->
    <add name="SQL Server Compact Edition Data Provider" invariant="System.Data.SqlServerCe" description=".NET Framework Data Provider for Microsoft SQL Server Compact Edition" type="System.Data.SqlServerCe.SqlCeProviderFactory, System.Data.SqlServerCe, Version=3.5.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" />
    <add name="SQL Server Compact Edition Client Data Provider" invariant="Microsoft.SqlServerCe.Client" description=".NET Framework Data Provider for Microsoft SQL Server Compact Edition Client" type="Microsoft.SqlServerCe.Client.SqlCeClientFactory, Microsoft.SqlServerCe.Client, Version=3.5.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" />
  </DbProviderFactories>
</system.data>

The SQL Server CE Data Provider element (for v3.1 disguised as v9.0.242.0) appears to conflict with the SQL Server Compact Edition (SSCE) Data Provider v3.5.0.0, which is the correct version for Orcas March 2007 CTP, when running under Windows Vista. Version 3.5 supports the Microsoft Synchronization Services (OCS) CTP, has new data types, and other improvements. Note: The machine.config file is present only in the .NET Framework 2.0's CONFIG folder. The other framework folders (1, 1.1, 3.0, and 3.5) don't have a CONFIG folder.

Here's a screen capture of the line to edit in your machine.config file (click for full size image):

And just to prove that the fixes work, here's a screen capture of Server Explorer showing two remote SQL Server 2005 Express instances and a local SQL Server 2005 Compact Edition Test.sdf file created when the connection was made (click for full size image):

Caution: Installing Orcas March 2007 CTP without installing SQL Server 2005 Express (SSX) requires that you change the connection strings for many sample applications, such as those for LINQ to SQL, from local user instances of Northwind.mdf to remote instances of the Northwind sample database. My Updated Orcas March 2007 CTP LINQ C# Samples post provides an example for the Sample Queries project's LinqToSqlSamples class.

Note: Here's a link to an ADO.NET Orcas post from a tester with the problem solved here. Two more confirmations here and here.

Update 3/19/2007: Use Orcas's Server Explorer, not SSMS, to manipulate SSCE data files. Server Explorer's Show Table Data context menu choice lets you edit SSCE table data.

Laxmi Narsimha Rao ORUGANTI from Microsoft India posted the following in the Microsoft Synchronization Services for ADO.NET forum regarding SSCE versioning issues:

With SQL Server 2005 (RTM, SP1, SP2), the version of SQL SERVER COMPACT EDITION integrated with it is 3.0/3.1 (Note: DLL versions would still remain as 3.0.xxxx.0). SQL Server CE 3.5 which is part of ADO.NET Sync Services CTP is not integrated with database management tool SSMS. We would encourage you to use ORCAS to manipulate the Sync Services databases created on client side. SQL Server CE 3.5 is fully integrated with ORCAS. Use Database Explorer (or Server Explorer). We are also working towards to integrate with Orcas Express editions but nothing is concrete or materialized yet so no promises.

Monday, March 05, 2007

More About LINQ Changes in the Orcas March 2007 CTP

Julie Lerman's A few of the many syntax changes in VB (and Linq for SQL queries) post describes changes to LINQ to SQL parameter, entity reference, and anonymous type syntax with before and after examples. Her Stored Procs in LINQ to SQL in March CTP (The VB Version) post describes the "dramatic" syntax changes for stored procedures and the ability to drag-and-drop a stored procedure onto the LINQ to SQL modeler.

Julie includes a link to Mike Taulty's Stored Procedures in the March CTP C# post. Mike's also tracking C# changes in his "Orcas" March CTP, Finding Extension Methods, and "Orcas" March CTP - IEnumerable to DataTable posts.

Update 2/6/2007: Julie consolidated her LINQ and related updates in a LINQ and Entity Framework Resources for March Orcas CTP post to her Developer Blog. This post contains a very valuable set of links to LINQ to SQL, LINQ to DataSet, and Entity Framework resources, including Bob Beauchemin's Using stored procedures with EDM ObjectServices in the March CTP (with code) post.

Jim Wooley's Converting from VB LINQ to Orcas post gives you the changes required to conform LINQ-related VB projects from the LINQ May 2006 CTP to current Orcas standards. His Changed order of LINQ operators for VB 9 post explains why the Order By clause now comes before the Select list: To eliminate the requirement that Order By fields be members of the Select list. This change must be implented manually.

Note: Jim has joined LINQ gurus Fabrice Marguerie and Steve Eichert as a co-author of LINQ in Action for Manning Publications Co. The book will be a member of the Manning Early Access Program, so you can read the chapters as the authors write them.

The XML Team supplements its February 2, 2007 XML Features in the February CTP of Visual Studio “Orcas” post with more information on the bridge classes that let one use other System.Xml APIs over a LINQ to XML tree in The new LINQ to XML “Bridge Classes” to System.Xml. According to the authors:

LINQ to XML users can now create a tree in memory with an XmlWriter application or as the output of an XSLT transformation, validate a loaded tree against an XSD schema, use XPath 1.0 to query and XSLT 1.0 to transform the tree, and so forth.

Updated Orcas March 2007 CTP LINQ C# Samples

Charlie Calvert has posted updated replacements for all downloadable C# LINQ samples for the Orcas March 2007 CTP. You can find links to the original C# and VB LINQ samples by searching online help for LINQ samples. Here's a list of the current sample set (not the same as online help's list):
  • Sample Queries -- Provides examples of query operations for LINQ to Objects, LINQ to SQL, LINQ to XML and LINQ to Datasets. (These are the "101 LINQ Queries" samples.)
  • Object Dumper Sample -- Includes a library that you can add to your solution to output the results of LINQ queries for testing purposes.
  • Windows Forms Data Binding Sample -- Demonstrates how to use LINQ in Windows Forms databinding scenarios.
  • Reflector Sample -- Generates an HTML document that outlines the public API for a given assembly.
  • Expression Tree Visualizer Sample -- Provides a working implementation of a visualizer that can be run inside the Visual Studio debugger to view the contents of an expression tree.
  • Data Folder -- Provides special version of the Northwind database and XML files used by other LINQ samples.
  • LINQ to Northwind Sample -- Provides examples of using LINQ to SQL to query a database.
  • XLinqIntro Sample -- Introduces basic LINQ to XML features in a console application.
  • PasteXmlAsXlinq Add-In Sample -- An AddIn class to paste XML on the clipboard as C# LINQ to XML code.
  • RSS Sample -- This sample acts as a tiny web server that aggregates several RSS feeds. An Internet connection is required.
  • Simple Lambda Expressions Sample -- Provides examples of simple lambda expressions.
  • Dynamic Query Sample -- Illustrates how to create LINQ queries dynamically at runtime.

Charlie also produced a seven-minute "overview" video that demonstrates how to run several of the samples.

Running Samples from a Remote SQL Server Instance

If you don't install a local instance of SQL Server (to make the Project Designer's Properties window operable), you must change the connection strings for LINQ to SQL samples. For example, the Sample Queries project's LinqToSqlSamples class requires commenting all existing connection string code and writing a new connection string for the remote instance (OAKLEAF-VS20 for this example):

public class LinqToSqlSamples : SampleHarness { //private readonly static string dbPath = ...; //private readonly static string sqlServerInstance = ...; //private readonly static string connString = ...; //private readonly static string connString = ...;

private readonly static string connString = @"Server=OAKLEAF-VS20\SQLEXPRESS; Database=Northwind;Integrated Security=SSPI";

The remote instance must have the Northwind sample database installed by executing the Instnwnd.sql script or attaching the Northwind.mdf file after you run the SQL2000SampleDb.msi installer.

Sunday, March 04, 2007

Entity Framework Issues in Orcas March 2007 CTP

Following are ADO.NET 3.0 Entity Framework and LINQ to Entities issues and limitations excerpted from the Visual Studio Code Name “Orcas” Release Notes. The information is reprinted here because the release notes don't appear to be widely read.

Note: This post supplements my earlier "Orcas March 2007 CTP Installation Problems" post.

The issues and limitations fall into three classes:

  • SQL Server 2005 [Express] as the data source
  • SQL Server 2005 Compact Edition (SSCE) as the data source
  • LINQ to SQL issue specific to ASP.NET

ADO.NET 3.0 Entity Framework and LINQ to Entities General Issues and Limitations (apply to SQL Server or SSCE as the data source):

23. ADO.NET Entity Framework: Model and Target must be in different namespaces.

To resolve this issue

The Namespace attribute in the Schema element of the Model (.csdl) file should be different from the one in the Target (.ssdl) file. "ADO.NET vNext" throws an exception at runtime if they are the same.

24. ADO.NET Entity Framework: 1:1 relationships are not supported.

1:1 relationships cannot be mapped into the conceptual models of the Entity Data Model.

To resolve this issue

If a 1:1 relationship is present in the database, it can be mapped to a single entity (using entity splitting) if the two tables share the same primary keys.

25. Support for ASP.NET projects.

Assemblies containing ADO.NET Entity Data Models must be compiled outside the ASP.NET website project. They can be used in ASP.NET projects by copying the assembly into the “bin” website directory or adding a reference to them. The CSDL, MSL and SSDL files should also be copied into “bin”. Please refer to the ADO.NET vNext Web sample for more information about how to deploy, locate and load the appropriate CSDL, MSL and SSDL files.

26. Entity Framework requires all tables to have primary keys.

The Entity Data Model requires all entities to have keys. When the ADO.NET Entity Data Model Wizard generates files from a database table without a primary key, the project will not compile until a key is specified in the model files. The wizard will mark these places in the files with element names prefixed with the string "TODO". The wizard also adds warning messages to the Visual Studio task window.

27. LINQ to Entities sample: Working with the modified database.

The sample application should automatically mount the modified Northwind Database. If it is not successful or you have a different version you'd like to use, you can manually mount the database and change the connection string. To change the database that is used by the LINQ to Entities Samples, please change the connection string contained in the “Provider Connection String” setting of the Entity Framework connection string. If you attempt to use the App.Config for a connection string, please see the documentation.

28. LINQ to Entities sample: Adding or changing Entity Framework files.

If you add or change Entity Framework files (e.g., csdl, msl, etc), make sure to have the "Copy To Output" setting in Visual Studio set so that the files are included with any builds.

30. SQL Server Authentication in ADO.NET Entity Data Model wizard.

There is a known issue in the ADO.NET Entity Data Model wizard with using SQL Server authentication and choosing “Yes, include the sensitive data in the connection string”. The wizard disappears after you click “OK”.

To resolve this issue

Either use Windows Authentication or choose “No, exclude sensitive data from the connection string”. This issue is being targeted to be fixed for ORCAS Beta1.

ADO.NET 3.0 Entity Framework and LINQ to Entities General Issues and Limitations Specific to SQL Server Compact Edition (SSCE) 3.5:

7. SQL Server Compact Edition: No support for server-generated keys and server-generated values.

When using the ADO.NET Entity Framework, an entity’s keys may be marked as server generated. This enables the database to generate a value for the key on an insert (entity creation). Additionally, zero or more properties of an entity may be marked as server generated values. A SQL Server Compact Edition database may generate default values for null-valued properties (if a default value has been specified as part of the column definition) when an entity is created or updated. This release of SQL Server Compact Edition, when it is used with the ADO.NET Entity Framework, does not support entities with server-generated keys or values, even though such entity types might be defined in the Model (.csdl) or Target (.ssdl) files.

For more information, see the SQL Server Compact Edition Forum.

8. SQL Server Compact Edition: Paging queries not supported.

Paging queries are intended to support stateless paging (scrolling or windowing) through the results of a query. Paging queries in the ADO.NET Entity Framework can be specified by using the LINQ Skip and Take operators. For example, customers.OrderBy(c => c.Name).Skip(100).Take(20) Paging queries may also be expressed by using the SKIP, LIMIT, and TOP constructs of Entity SQL. For example: SELECT value c FROM NW.Customers AS c ORDER BY c.Name skip 100 limit 20; This release of SQL Server Compact Edition, when it is used with the ADO.NET Entity Framework does not support paging queries.

For more information, see the SQL Server Compact Edition Forum.

9. SQL Server Compact Edition: Full outer joins not supported. Entity SQL supports multiple joins including inner joins, left outer joins and full outer joins. This release of SQL Server Compact Edition does not support Entity SQL queries with full outer joins that use the ADO.NET Entity Framework. As an example, the following query will not be supported: SELECT c.Name, c.Id, o.Id FROM NW.Customers AS c full OUTER JOIN NW.Orders AS o ON c.Id = o.CustomerId

For more information, see the SQL Server Compact Edition Forum.

10. SQL Server Compact Edition: No support for COLLATE subclauses in the ORDER BY clause of an Entity SQL query. Entity SQL enables a COLLATE subclause to be specified as part of each key in an ORDER BY clause. The COLLATE subclause is applicable only for string-valued expressions, and determines the comparison semantics to use for that expression. This release of SQL Server Compact Edition, when it is used with the ADO.NET Entity Framework, does not support the use of a COLLATE subclause in the ORDER BY clause of an Entity SQL query. The following query will not be supported: SELECT value c FROM NW.Customers AS c ORDER BY c.Name COLLATE Traditional_Spanish_ci_ai

For more information, see the SQL Server Compact Edition Forum.

11. SQL Server Compact Edition: No support for command time-outs.

The ADO.NET Entity Framework enables time-outs for commands to be specified by using the ObjectContext.QueryTimeout property or the EntityCommand.CommandTimeout property. This release of SQL Server Compact Edition, when it is used with the ADO.NET Entity Framework, does not support time-outs. That is, the command time-out must not be set to a value other than zero. If a connection time-out property is set, a NotSupportedException(“CommandTimeout”) exception is raised by the SQL Server Compact Edition database.

For more information, see the SQL Server Compact Edition Forum.

12. SQL Server Compact Edition: Supports only Unicode strings.

The ADO.NET Entity Framework provides support for both Unicode and non-Unicode strings. This release of SQL Server Compact Edition supports only Unicode strings. Literal <literal> of type 'String' is not supported by the current provider. The 'near constant literal’ exception is raised by SQL Server Compact Edition in non-Unicode strings.

For more information, see the SQL Server Compact Edition Forum.

13. SQL Server Compact Edition: Limited support for Language Integrated Query.

The ADO.NET Entity Framework supports the Language Integrated Query. This release of SQL Server Compact Edition when it is used with the ADO.NET Entity Framework has limited support for Language Integrated Query. The release has been tested for the Entity SQL queries

For more information, see the SQL Server Compact Edition Forum.

14. SQL Server Compact Edition: Time-out in transaction scope. If the queries in a transaction scope take too long to finish and the transaction scope times out, the data might get committed to the SQL Server Compact Edition database.

To resolve this issue

To avoid such a situation, increase the time-out value.

For more information, see the SQL Server Compact Edition Forum.

LINQ to SQL Issue Specific to ASP.NET

29. LINQ to SQL assembly is not yet enabled for partial trust.

In this CTP, LINQ to SQL cannot be used in ASP.NET medium trust scenarios.

To resolve this issue

Full trust is required in this CTP. We are working on enabling partial trust.

These lists of issues will be supplemented by later posts as I test SSCE, Entity Framework, and LINQ projects under Windows Server 2003 SP1, Windows Server 2003 R2, Windows XP SP2, and Vista.