Over a million developers have joined DZone.

Batch Update Support in ASP.NET Web API OData

·

The ASP.NET Web API 2 OData includes some new features including the support for batch update. This features allows us to send a single request to the OData endpoint with a bunch of changes made to the entities and ask the service to persist them in one go instead of sending individual request for each change made by the user. This reduces the number of round-trips between the client and the service. 

To enable this option, we need to pass an additional parameter to the MapODataRoute method along with other routing details we discussed in an older post. Following statement shows this: 

GlobalConfiguration.Configuration.Routes.MapODataRoute("ODataRoute", "odata", model,new DefaultODataBatchHandler(GlobalConfiguration.DefaultServer));

I have a CustomerController that extends EntitySetController and exposes OData API to perform CRUD and patch operations on the entity Customer, which is stored in a SQL Server database and accessed using Entity Framework. Following is code of the controller: 

public class CustomersController : EntitySetController<Customer, int>
{
    CSContactEntities context;

    public CustomersController()
    {
        context = new CSContactEntities();
    }

    [Queryable]
    public override IQueryable<Customer> Get()
    {
        return context.Customers.AsQueryable();
    }

    protected override int GetKey(Customer entity)
    {
        return entity.Id;
    }

    protected override Customer GetEntityByKey(int key)
    {
        return context.Customers.FirstOrDefault(c => c.Id == key);
    }

    protected override Customer CreateEntity(Customer entity)
    {
        try
        {
            context.Customers.Add(entity);
            context.SaveChanges();
        }
        catch (Exception)
        {
            throw new InvalidOperationException("Something went wrong");
        }

        return entity;
    }

    protected override Customer UpdateEntity(int key, Customer update)
    {
        try
        {
            update.Id = key;
            context.Customers.Attach(update);
            context.Entry(update).State = System.Data.Entity.EntityState.Modified;

            context.SaveChanges();
        }
        catch (Exception)
        {
            throw new InvalidOperationException("Something went wrong");
        }

        return update;
    }

    protected override Customer PatchEntity(int key, Delta<Customer> patch)
    {
        try
        {
            var customer = context.Customers.FirstOrDefault(c => c.Id == key);

            if (customer == null)
                throw new InvalidOperationException(string.Format("Customer with ID {0} doesn't exist", key));

            patch.Patch(customer);
            context.SaveChanges();
            return customer;
        }
        catch (InvalidOperationException ex)
        {
            throw ex;
        }
        catch (Exception)
        {
            throw new Exception("Something went wrong");
        }
    }

    public override void Delete(int key)
    {
        try
        {
            var customer = context.Customers.FirstOrDefault(c => c.Id == key);

            if (customer == null)
                throw new InvalidOperationException(string.Format("Customer with ID {0} doesn't exist", key));

            context.Customers.Remove(customer);
            context.SaveChanges();
        }
        catch (InvalidOperationException ex)
        {
            throw ex;
        }
        catch (Exception)
        {
            throw new Exception("Something went wrong");
        }
    }
}

Let’s use the batch update feature in a .NET client application. Let’s try adding a new customer and update an existing customer in the Customers table. Following code does this: 

Container container = new Container(new Uri("http://localhost:<port-no>/odata"));

var firstCustomer = container.Customers.Where(c => c.Id == 1).First();
firstCustomer.Name = "Ravi Kiran";
container.UpdateObject(firstCustomer);

var newCustomer = new Customer() { Name="Harini", City="Hyderabad", Department="IT"};
container.AddToCustomers(newCustomer);

var resp = container.SaveChanges(SaveChangesOptions.Batch);

The last statement in the above snippet sends a batch request containing two requests: one to add a new customer and one to update an existing customer. The update operation calls the patch operation exposed by the OData API. 

In next post, we will see how to perform batch update in a JavaScript client. 

Happy coding!

Topics:

Published at DZone with permission of Rabi (ravi) Kiran, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}