Logging in Entity Framework

Logging in Entity Framework

When working with any ORM tool, it can sometimes be helpful to see just what, exactly, is being sent to the underlying data store.  This can help identify bugs as well as performance issues in how the query is being performed (or how many queries are being performed, in the case of SELECT N+1 problems).  There are several existing tools available that provide assistance with this:

Sometimes, though, you want to be able to log what EF is doing to a standard logger, whether using the built-in System.Diagnostics calls, or a logging tool like log4net or NLog.  In this case, there’s a very simple way to achieve this.  Entity Framework exposes a Log property, that accepts any Action<string> type. What this means is you can specify a simple lambda expression that takes in a string and doesn’t return anything, and that expression will be executed whenever EF performs a database operation.  You can specify this in the DbContext constructor if you want every operation to be logged during the lifetime of the DbContext, like in this example:

In this example, I’ve added logging to the MvcMovie sample application associated with this MVC 5 tutorial.  With this in place, using a tool like DebugView from SysInternals (or the Debug output window in Visual Studio, but DebugView is nice to have for viewing on production machines) will show:

debugview_ef

 

Now, in this case, you’ll see that refreshing the app again and again will result in these same two queries being executed. That’s because the sample is just a starting point, not something you want to actually use in a real application.

Shameless Plugs Follow…

If you want to see how to go from such an application to something that you can easily maintain and that performs and scales effectively, I recommend you check out my N-Tier Architecture and Domain-Driven Design courses on Pluralsight. At a minimum, you should remember that New is Glue and avoid things like this in your controllers:

This kind of code tightly couples your controller to your data access implementation, and in fact to your database itself, making it extremely difficult to test the controller. It’s also the wrong level of abstraction to have in your UI layer, and thus results in a lot more duplicate code in the UI layer that should belong somewhere else. In my workshops with clients, we start out with code like this and write tests for it, requiring a test database and a lot of extra effort (see for example Integration Testing Entity Framework with Migrations). Then, we refactor the code and introduce Domain-Driven Design style architecture, resulting in a much more modular and maintainable application that is easier to extend as well as test.

If you or your team are unsure of how to get your existing or new application into a state where it can more easily be maintained, extended, and tested, contact me and I may be available to help.

  • Unfortunately, the Database.Log implementation is limited to EF6. It is not supported prior to 6, nor will it be included in EF Core as they are moving to the ILogger strategy from ASP.Net Core.