Search code examples
c#connectionodataasp.net-web-api2dispose

oData queries and Disposable SQL connection


When implementing an oData service using WebApi 2.0, the standard practice is to expose an IQueryable from your service to the ApiControllers' action. This way the framework can apply the oData query to your IQueryable.

I'm currently reading, amongst others, about how important it is to always call Dispose on your database connections. Preferably by using the "using" statement like so:

using (SqlConnection connection = new SqlConnection(connectionString))
{
     connection.Open();
     // Execute operations against the database
} // Connection is automatically closed.

My question is: When is the database connection closed in the case of oData? You obviously can't dispose the connection yourself, before the framework applies the oData query - this would throw an exception.

A side topic would be: do you agree on exposing IQueryable<> from your services? I've read about this and it's a long debated issue - people argue that the database work should be contained in the repository, while others like to give the querying freedom to the services' clients. I agree with containing the queries in the repository, but in the case of oData I don't like to over-complicate things, if the framework espectes IQueryable, then I give it IQueryable. What do you think ?


Solution

  • Usually in such cases database connection is closed when asp.net controller instance is disposed. Suppose you use Entity Framework context to do queries. Then you create (maybe lazily) that context instance when needed and then override Dispose method of ODataController and dispose it there. For example, take a look at this article: http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-v4/create-an-odata-v4-endpoint.

    I personally never use this approach because I prefer to have more control on allowed operations. However, see no harm in certain cases to allow read access to certain tables via IQueryable approach described - in cases when on client you have rich filtering possibilities. In such case, you will reinvent this approach anyway, because you will use some custom filters, or accept a lot of parameters to your querying method.