RTM is here!

ADO.NET Data Services (aka “Project Astoria”) has Released!  Today marks the official RTM of Visual Studio 2008 SP1 and the .NET Framework 3.5 SP1, and we are thrilled to announce the official RTM of the ADO.NET Entity Framework and ADO.NET Data Services.

You can find more information and download SP1 at http://msdn.microsoft.com/data .

The remainder of this post will cover the changes and additions to the ADO.NET Data Services Framework since the Beta.  This post will just give a brief summary of each and we’ll follow up with more targeted posts overtime to get a bit deeper into the details.

Changes \ Enhancements:

Tweaks to the ATOM payload: We've made a few tweaks to the payload format based on feedback from the ATOM community and to enable us to land on a simpler overall set of semantics for CRUD operations across resources and links between resources.  One of the most significant improvements is that links/associations are now directly addressable so it’s clear when you are working with an link\association vs. working with a resource\entity.  Using the Northwind database schema as an example, to address the set of links between a Customer and their Orders, the following URI is available: http://myserver/myservice/Customers(‘ALFKI’)/$links/Orders.  This new $links segment allows associations to be addressed and manipulated directly.  We’ll follow up with additional examples and whitepapers showing the details of this syntax in future posts.

A handful of bug fixes J.

Tweaks to our optimistic concurrency support: We added support for the ‘*’ character to be used with conditional HTTP requests.  We also changed to use weak Etags instead of strong Etag values to better align with the HTTP spec and its current set of ammendums.

Tweaks to the .NET client library: The response object from the SaveChanges(…) method has changed to make it easier to get at all aspects (headers, etc) of each section of the data service response.  The most significant difference is the HasErrors properties from the *Response classes are removed.  Instead, if one or more errors occur during the processing of a call to SaveChanges(…), the method will throw an exception.  The exception contains a property to access the full response to determine which operations succeeded and which failed (assuming SaveChangesOptions.Batch was not used which provides “all or nothing” semantics).

Additional configuration of system limits: A number of system limits are now publically exposed via the IDataServiceConfiguration class enabling a data service author more control over the requests their service is willing to accept and process

Additional plug-in points in the processing pipeline: Just after URI syntactic analysis is complete, we have added a call out in the processing pipeline called OnStartProcessingRequest.  This call out enables custom service code to run at a very early point in the request processing pipeline.


“Add Service Reference” support for client proxy generation: The command line tool to generate client side types for a data service (datasvcutil.exe) can still be found in the \Windows\Microsoft.Net\Framework\V3.5 directory; however, we are pleased to announce the “Add Service Reference” feature in Visual Studio now supports accepting ADO.NET Data Service URIs.

Service versioning support: Data services now directly support a lightweight versioning scheme enabled via HTTP headers.  The scheme has been designed with the goal of enabling existing clients to work with new service versions (and vice versa) when safely possible.  The goal was taken as it seems for internet facing data services one needs to assume clients and services will rev at different speeds.

Control error messages: Data service authors can now easily control all error messages and associated status codes returned to a client as a result of an error while processing a data service request.  The HandleException method on the DataService class is now called for any exception that occurs while processing a request.  A data service author can then map any downstream exception to sections of the error message structure used by data services.

What’s Next….

We want to work on a round of blog posts to address a few of the common questions folks have when using data services.  We’ve got a number in mind already, but if you have a question/comment that would make a good blog post let us know.  We likely won’t be able to answer each with a full blog post, but we’ll try to address the common ones.

-Mike Flasko
Program Manager, ADO.NET Data Services

Comments (28)

  1. As has just been announced on several MSDN and product teams blogs , Service Pack 1 for .NET Framework

  2. It seems that the giant of software, Microsoft, is back to its track in post-Gates era! After announcing

  3. Here you go ! Install the latest bits of Astoria and play to your heart’s content …. Download here

  4. BenHayat says:

    Hi Mike;

    Congrats to you and the team for the RTM;

    Could you PLEASE verify and explain the status of the Silverlight "Client" side for Astoria? Is it completed now? Is the INotifyChange implemented for two-way binding?

    Where can I get docs for the Async commands and "How to" use them?

    Please give us detail on this subject! Thank you in advance!


  5. [These code snippets are based on features in the SP1 RTM release, Read about it here : RTM is here!

  6. I’ve been sort of under a rock for a while, but I thought I’d come out for a minute to celebrate. Today

  7. Nachdem meine Ankündigung gestern eher spartanisch ausgefallen ist, möchte ich heute noch ein paar Links

  8. David Cater says:

    I’d like to second BenHayat’s question above.  In particular:

    – I’m getting an exception now when using the Silverlight client.  Forum posting: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=3736840&SiteID=1 .

    – Is there documentation or sample code available for the new exception handling architecture using HandleException?  I like the sound of the description of it in the article, but I’m not sure what the "error message structure" is, how it is used, or how the error is exposed on the client side (particularly Silverlight).



  9. Balaji says:


    Can you post an example for ADO.NET Data Servics with Linq to XML



  10. Anshulee says:


    Can you pls describe how to delete a object which has a Foreign key? Let me describe the scenario

    I have a User with multiple UserProfile so UserProfile has a FK for User. To add a new User profile i write the following code

    UserProfile profile = new UserProfile();

    profile.UserIdentity = user;

    entityStore.AddObject("UserProfile", profile);


    entityStore.AddLink(profile.UserIdentity, "UserProfile", profile);

    entityStore.BeginSaveChanges(SaveChangesOptions.Batch, delegate(IAsyncResult asyncResult)

                   { entityStore.EndSaveChanges(asyncResult); }, null);

    This works and a new Profile is added.

    Now i want to delete this profile.

    In beta the following code worked

                   var profile = entityStore.UserProfile.Expand("UserIdentity").Where(p => p.profileid == profileid);

                   UserProfile userProfile = profile.First<UserProfile>();


                   entityStore.DetachLink(profile, "UserIdentity", profile.First<UserProfile>().UserIdentity);

                   entityStore.BeginSaveChanges(SaveChangesOptions.Batch, delegate(IAsyncResult asyncResult)

                   { entityStore.EndSaveChanges(asyncResult); }, null);

    But this doesn’t work now. I’ve tried with DeleteLink and also with

    entityStore.DetachLink(userProfile.UserIdentity, "UserProfile", userProfile) but no luck …all i get is "There was an error processing this request..

    I culd not find a sample in th RTM traning kit for this scenaro either. Please help here..



  11. Ruben says:

    Paging support (i.e., TotalCount). Without it, you’re completely in the dark as to how bad a query is (e.g., "page 1 of 1234567"), what to expect ("1 [2] 3 4" v.s. "where am I?"), or to make a reasonable guess how far you must skip ("page 1 of 8; I need something beginning with an S… let’s try page 6" vs. "Next, Next, Next, Next, Next, Next, *curse*, Previous"). It’s my pet peeve to skip v1.

    Something like http://myserver/data.svc/Customers(’ALFKI’)/Orders/$count?$filter=…

    Support for aggregates in general would be cute, but not that important. Aggregate calculations are ideally suited for business methods on a service, because when you start, you’ll have to add group by and subqueries and … And before you know it you’ve built SqlToUrlToLinqToSql.

  12. RoryBecker says:

    Where is the main Astoria discussion happening. forum/newsgroup something else? Best place to ask questions please. Preferably frequented by some MS Staff/MVPs who are in the know

  13. Ruben: for paging, for this release you can use next/pev instead of page number. Total count and page numbers are tricky to compute without triggering an expensive operation on the database, so we want to be careful on how we introduce support for this. Regarding aggregates…yes, we got several requests for it, we’ll look at it eventually but there is a bunch of other stuff that we’re getting ask for as well.


  14. Rory: the best place for Astoria discussion is the Astoria forum:



  15. It’s amazing how much information is there in our email archives. Now that we’ve shipped the thing, I

  16. Nick Williams says:

    I’m also distraught about the lack of efficient results count.  My main ajax control (a grid) utilizes on-demand data fetching as the grid is scrolled.  I need an accurate count to be able to allow skipping through records by dragging the scroll bar and indicating which records are visible as a range – along with using the count value with the scroll bars themselves to size the grab region.

    Retrieving the count of records in an efficient manner is an absolute necessity for modern AJAX.

  17. Hi Nick,

    Yes, I agree that not having count is painful. Hopefully we’ll be able to address that soon.

    That said, I’ve seen various AJAX clients that do without it for various reasons. For example, the Yahoo mail interface dynamically adjusts the scrollbar and content in general as you scroll down and they find more about the items available.

    As a bit of background: for the cases where data is in a relational database, in general obtaining the row count is a quite expensive operation (often it involves counting rows in the most compact index/heap available). There are shortcuts sometimes, but they introduce a non-uniform way of finding out the count.

    Also, naturally, the count is pretty much always innacurate. The moment the value left the server, it may already have chanced undernead; also, page counts can change from page to page. So for various reasons certain level of innacuracy needs to be tolerated by the app.


  18. Nick Williams says:

    Perhaps I’ve put too much emphasis on the accuracy side of things.  You can see what I’m attempting to do here:  http://www.siteartwork.de/livegrid_demo/

    If it’s off by 2 out of 1,000 due to new inserts – no big deal.  But I do need to know whether there’s 100 or 5,000 results.  If it takes 2 seconds of extra processing to determine that there’s 5000 results – that’s no big deal as I’m not going to ever have to get that count again for the view.  This same requirement applies to many other things I will need to do with my project – letting the user know they’re on page 1 of 20 in a particular category, that their search for some broad term has returned an enormous amount of results and that they should refine things futher, etc.

    From what I’ve been reading lately, I’m not sure that it’s even possible to count the entities returned server side while using a filter or other logic via the URI. Is there *any* way to determine the number of results being returned through a URI such as

    /Orders?$filter=ShipCountry eq ‘France’

    that can be self-contained in the data layer (ie. no counting rows client side)?  The answer to that question is the maker/breaker.

    I appreciate you taking your time to reply.

  19. Hi Nick,

    For the case where you’re using a database as a backend (e.g. it’s not your LINQ implementation), which is the most common case, I don’t think there is a way of doing this short of looking at the filter expression yourself, which I would strongly encourage not to.

    I checked out the grid sample and the grid looks really, really nice. Impressive job.

    For something like a data service, you’d have to dynamically fix up the scrollbar as you find out that more rows are available, or introduce a next/prev kind of UI (which I understand that doesn’t fit well in the grid as it is today).

    I’ll keep this in the back of my mind. If I come up with some approach to do this I’ll post it somewhere.


  20. Nick Williams says:

    I am truly flabbergasted that there is no way to determine the number of results returned.  Data Services seems kind of pointless to me, if this simple requirement can’t be fulfilled.

  21. Nick Williams says:

    If we DID provide a next/previous page we wouldn’t even know when to disable the "NEXT" button unless the client-side count happened to be less than our $top value!  This is so silly!  Why even provide paging if you can’t tell what page you’re on!?  Why waste your time offering paging functions if you didn’t plan to let us know when we’re on the last page?  This is so absolutely silly.  Data Services paging belongs on the from page of The Daily WTF – really.

  22. Jay Smith says:

    .NET Framework 3.5 SP1 and Visual Studio 2008 SP1 Released

  23. I have to agree with Nick.  Data Services without paging is silly.  The product is not feature complete until this is added.

  24. @Robert: we heard that loud and clear from all of you guys, so we’re working to add that feature for the next release. We should have the feature built into the first public beta/ctp/whatever release that we ship.

    Standard disclaimer applies: there is never a guarantee about features for unreleased products until they hit RTM.


  25. Thanks Pablo, good to hear —

    For now, I’m using a WebGet method to retrieve the count and I’ve learned that field names in the string predicate must specify the "it" namespace … such as "it.Category == "Overstock""

    Can you explain this?  I can’t find any documentation on "it"



    public int CountOrders(string prediate)


          // Note: field names in the prediate must be prefixed with "it."

    return CurrentDataSource.Orders.Where(prediate).Count();


    Thanks again!

  26. Jay Smith says:

    .NET Framework 3.5 SP1 and Visual Studio 2008 SP1 Released

Skip to main content