Mike Taulty's Blog
Bits and Bytes from Microsoft UK
ADO.NET Data Services - Batching in Action

Blogs

Mike Taulty's Blog

Elsewhere

I did a talk on Data Services at DevDays, Amsterdam last week and so I had to take a rather speedy look at batching support as that had been added to the VS 2008 Sp1 bits since the previous preview.

Batching is explained up here but here's just a little example of using it.

If we take "hello world" style service that we created back in this post and we were to do something like this from the .NET client side code;

  static void Main(string[] args)
  {
    Console.ReadLine();

    NorthwindEntities proxy = new NorthwindEntities(
      new Uri("https://localhost/SecureSite/Secure/Service.svc"));

    foreach (Shippers s in proxy.Shippers)
    {
      Console.WriteLine(s.ShipperID);
    }

    foreach (Employees e in proxy.Employees)
    {
      Console.WriteLine(e.EmployeeID);
    }

    Console.ReadLine();
  }

and if we were to go ahead and trace that traffic with Fiddler then we'd see;

image

That is - we see and HTTP GET request for Shippers and then another one for Employees. Now, if these 2 entity sets are related then we can use the $expand query string operator in order to bring back the related data as the response to a single GET but it would be easier even here just to try and use batching to reduce the number of round trips and we can do that with something like;

static void Main(string[] args)
  {
    Console.ReadLine();

    NorthwindEntities proxy = new NorthwindEntities(
      new Uri("http://mthpvista/SecureSite/Secure/Service.svc"));

    DataServiceResponse responses =
      proxy.ExecuteBatch(
        new DataServiceRequest<Shippers>(new Uri("Shippers", UriKind.Relative)),
        new DataServiceRequest<Employees>(new Uri("Employees", UriKind.Relative)));

    foreach (QueryResponse item in responses)
    {
      foreach (Shippers s in item.OfType<Shippers>())
      {
        Console.WriteLine(s.ShipperID);
      }
      foreach (Employees e in item.OfType<Employees>())
      {
        Console.WriteLine(e.EmployeeID);
      }
    }

    Console.ReadLine();
  }

So, now we're using ExecuteBatch in order to send any number of queries to the server in a single shot and we get back a number of responses. If we look at Fiddler, we see;

image

and so we've sent a single POST to the $batch endpoint and in that single post is a request for 2 GET operations - one for Shippers and one for Employees and then we get back 2 responses in the response stream.

The other side of batching ( and possibly the more common one ) is when you want to do multiple inserts, updates, deletes. Again, I could see using this when I want to minimise round-trips but, more so, when I want to get a bunch of changes submitted to the server as a single operation rather than a set of separate posts. I guess the classic example would be to insert a customer with 3 orders - you'd really like this to happen in a single post but I guess that RESTful systems have to have a mechanism for dealing with the intermediate case if you do submit the inserts as 4 separate POSTs.

If I use code such as;

static void Main(string[] args)
  {
    Console.ReadLine();

    NorthwindEntities proxy = new NorthwindEntities(
      new Uri("http://mthpvista/SecureSite/Secure/Service.svc"));

    for (int i = 0; i < 3; i++)
    {
      Customers newC = new Customers()
      {
        CustomerID = string.Format("ACME{0}", i),
        CompanyName = string.Format("Comp{0}", i)
      };
      proxy.AddToCustomers(newC);
    }
    proxy.SaveChanges();

    Console.ReadLine();
  }

 

then what I see as a result of my inserts is;

image

That is, I get 3 POSTs for my 3 customers that are being inserted. There's an easy way to cut that down to a single POST which would be to change the way in which I'm calling SaveChanges in order to pass a SaveChangesOption value of Batch;

  static void Main(string[] args)
  {
    Console.ReadLine();

    NorthwindEntities proxy = new NorthwindEntities(
      new Uri("http://mthpvista/SecureSite/Secure/Service.svc"));

    for (int i = 0; i < 3; i++)
    {
      Customers newC = new Customers()
      {
        CustomerID = string.Format("ACME{0}", i),
        CompanyName = string.Format("Comp{0}", i)
      };
      proxy.AddToCustomers(newC);
    }
    proxy.SaveChanges(SaveChangesOptions.Batch);

    Console.ReadLine();
  }

and now what I see is a single POST sent to the $batch endpoint with the request for 3 inserts in it;

image


Posted Thu, May 29 2008 12:06 PM by mtaulty

Comments

Christopher Steen wrote Link Listing - May 29, 2008
on Thu, May 29 2008 8:34 PM
AJAX  Cool ScriptManager stuff I missed... [Via: Jay Kimble ] ASP.NET  ASP.NET Memory: Thou shalt not...
Weekly Links: ASP.NET MVC, .NET, ADO.NET Data Services, Silverlight, WPF… | Code-Inside Blog International wrote Weekly Links: ASP.NET MVC, .NET, ADO.NET Data Services, Silverlight, WPF&#8230; | Code-Inside Blog International
on Mon, Jun 2 2008 1:33 PM
Wöchentliche Rundablage: ASP.NET MVC, .NET, ADO.NET Data Services, Silverlight, WPF… | Code-Inside Blog wrote W&ouml;chentliche Rundablage: ASP.NET MVC, .NET, ADO.NET Data Services, Silverlight, WPF&#8230; | Code-Inside Blog
on Mon, Jun 2 2008 1:33 PM
Hot Topics wrote Mike Taulty beats on ADO.NET Data Services new features
on Fri, Jun 13 2008 6:27 AM
Rather than just listing what&amp;#39;s new, Mike tries them all out! Yay Mike. First he tackles Authentication
Mike Taulty's Blog wrote Silverlight and ADO.NET Data Services ( 2 )
on Mon, Jun 30 2008 3:39 PM
Following on from this last post, if I start to edit the data in the grid and change some value then...