Azure Mobile Apps: Writing a Fast Custom DomainManager, Part 3

Picking Up From Last Time

Last time, I finished the overview of the helpers afforded by the MappedEntityDomainManager and how they could be used to easily implement a custom DomainManager that maps an ITableData DTO class to a database table with an integral primary key, and I profiled the SQL that was generated by performing an ID lookup as well as the SQL that was generated by querying the OData endpoint of a TableController that uses this custom DomainManager. I explained why the SQL generated by this custom DomainManager is superior to the SQL generated by another custom DomainManager called the SimpleMappedEntityDomainManager, taken from an MSDN blog post. This post, I will conclude the discussion by explaining how to test the insert/update/delete methods of a TableController and show the generated SQL.

Test Setup

In a real project, the ideal test setup would be to have a nice separation of dependencies and a suite of automated tests on the DomainController. However, that’s well beyond the scope of what we’re discussing here, so instead I want to introduce a simpler, but more manual way to test the TableController with the custom DomainManager. For these tests, I’ll continue to hit the TableController directly as I did in the previous post. However, the methods that we want to test require specifying a different HTTP verb than GET, so we must use a tool that lets us do so rather than simply entering the request URL in the address bar of a browser. For quick and dirty REST API requests, I initially used Postman, a Chrome app that lets you craft and execute HTTP requests to test REST APIs. But then I thought to myself that it would make more sense to test using the actual official JavaScript client, and it turns out to be quite simple to do! Just add an HTML page to your mobile app project and paste this markup in:

In summary, all the page does is reference the JavaScript client library for Azure Mobile Services and create a client instance saved in a global variable for easy access. If you refer to the example code from the Azure documentation link, you will notice that I omitted the AppKey argument. You can safely do this for local testing and the client library will still work. To confirm, I brought up my browser’s developer tools and entered the following line:

This performs an AJAX request to the server and returns a Promise, but typing callback handlers into the console is relatively tiresome compared to just checking the Network tab and viewing the results there. I observed that the expected request was made: a GET to /tables/CustomEntity/1, and the response was the JSON representation of my data. I already profiled the SQL generated by lookups and queries in my last post, so let’s move on to the insert/update/delete SQL instead.


While testing the insert functionality, I noticed a discrepancy between the behavior of my controller and the sample TodoItem controller: my controller would throw an exception if I tried to insert without providing an ID. It’s pretty common for DB tables with integer keys to have these values generated by the database and it would be uncommon to require an ID value to be passed only to be discarded. I did a little digging with a disassembler and quickly found that the reason for this behavior is simply that the base implementation of MappedEntityDomainManager.InsertAsync will assign a GUID value to the DTO’s Id value prior to attempting to map the DTO to the entity type, if Id is null. This of course causes attempts to parse the Id as an integer to fail. It’s a simple fix, though; simply override InsertAsync in the custom domain controller and assign a string representation of a valid integer to the DTO’s Id property before calling the base InsertAsync method:

Now you can insert with the client library without needing to specify an ID. My custom table only has a Data column in addition to the ones required to support the ITableData interface, so this is all the code you need to insert a row using the client library:

If you inspect the request, you’ll see that this is translated into a POST with a JSON body. The SQL profiler shows this statement was executed:

And I’m pleased to say that I don’t see anything alarming there at all! The response contains the generated ID, so let’s try sending an update request to update the created row:

The network tab will show a PATCH request with a JSON body. Normally, a REST API uses PUT for update requests, but PATCH is also sometimes used. In general, PUT is understood as a request to update an entire entity, while PATCH is understood as a request only to update the specified columns, leaving the other columns unmodified. The profiler shows first a lookup query:

And then the update query:

The important thing here is that the lookup and update both reference the ID column in a good way that can be supported by indexes. Finally, let’s try a delete:

The network tab shows the expected DELETE request and the profiler shows first a lookup query exactly as above, and then the delete query:

And once again the query references the ID column according to best practices.


The default ID column provided by Azure Mobile Apps Quickstart is grossly inefficient, and the advice from the MSDN blogs on the topic resulted in a solution that took more lines of code while also yielding queries that would not scale well. In this series, I not only showed how you can write your own DomainManager implementation that will map mobile app service requests to and from tables with integer IDs, but also some of the plumbing in the parent classes that makes this process easy, allowing you to write less code while producing better queries against the backing database.


The following two tabs change content below.

Adam Anderson

Master Consultant at Falafel Software
Adam Anderson is a Microsoft Certified Solution Developer with over 19 years of experience. He started as a consultant using Delphi to rapidly deliver custom, high-quality business solutions in a wide variety of industries. His later experiences afforded him the opportunity to become familiar with a number of different products, technologies, and disciplines, including SQL Server and T-SQL, Oracle and PL/SQL, Crystal Reports, SQL Reporting Services, Internet Information Services, .NET Framework, LINQ, Entity Framework, CSS, HTML, Javascript, Kendo UI, ASP.NET MVC & Web API, ServiceStack, Command batch files, PowerShell, normalized relational database design, dynamic databases, and good object-oriented design based on design patterns and testability.