Logging and Intercepting Database Operations With Entity Framework 6.0

Introduction

Entity Framework 6.0 introduced the feature called "Logging SQL". While working with Entity Framework, it sends commands or an equivalent SQL query to the database to do a CRUD operation and this command can be intercepted by application code of Entity Framework. This feature of the Entity Framework is to capture an equivalent SQL query generated by Entity Framework internally and provide it as output.

How to enable SQL logging

The DbContext.Database.Log property can be set to delegate for any method that accepts a string as the parameter. Using this method, all SQL generated by the current context will be logged.

Syntax:

  1. public Entities() : base("name=Entities")   
  2. {   
  3.       Database.Log = delegate for method which accepts string as parameter;   
  4. }   
Example:

Suppose I have two database entities, EmployeeMaster and DepartmentMaster, and I want to log, the SQL generated by the Entity Framework.

database entity

The DbContext.DataBase.Log property accepts a delegate for the method that has a string parameter. The Console.WriteLine function has the same type of delegate, so we can assign this function to the Database.Log property of DbContext.
  1. public Entities() : base("name=Entities")  
  2. {  
  3.    Database.Log = Console.WriteLine;  
  4. }  
Test Code:
  1. static void Main(string[] args)  
  2. {  
  3.     using (Entities context = new Entities())  
  4.     {  
  5.         var data = context.EmployeeMasters.Where(p => p.Code.StartsWith("p")).ToList();  
  6.         var data1 = (from e in context.EmployeeMasters  
  7.                         join d in context.DepartmentMasters on e.DepartmentId equals d.DepartmentId  
  8.                         select new  
  9.                         {  
  10.                             Name = e.Name,  
  11.                             Department = d.Name  
  12.                         }).ToList();  
  13.     }  
  14.     Console.ReadLine();  
  15. }  
Output:

program output

Writing SQL Log into text file

We can also pass the SQL query to any other function. Only the condition is a function that must have the same delegate as the DataBase.Log property accepts.

For example suppose I want to write all SQL into a text file, so I create a custom function that accepts a string and writes it into the text file.

Custom function definition
  1. namespace CodeFirstTest  
  2. {  
  3.     public class WriteFile  
  4.     {  
  5.         public static void WriteSQL(string data)  
  6.         {  
  7.             string path = @"c:\SQLtrace.txt";  
  8.             File.AppendAllText(path, data);  
  9.         }  
  10.     }  
  11. }  
Now assign this custom function to the Database.Log property as a delegate.
  1. public Entities() : base("name=Entities")  
  2. {  
  3.        Database.Log = s=> WriteFile.WriteSQL(s);  
  4. }  
  5.   
  6. // Other way to pass function  
  7. public partial class Entities  
  8. {  
  9.        public Entities(): base("name=Entities")  
  10.        {  
  11.            Database.Log = WriteFile.WriteSQL;  
  12.        }  
  13.  }  
Output:

SQL Trace

What did it Log?

The following things are logged when the Database.Log property is set:
  • All SQL Commands

    • Equivalent SQL query for a normal LINQ query, eSQL and raw query (query that has a from clause).
    • Insert, update and delete command generated as a part of the SaveChanges method of context.
    • Relationship loading queries

  • All the Query Parameters
  • Date and Time when the command is started to execute
  • The approximate amount of time it takes to execute the command. This is the time required to send the command and get results back. It does not include time to read the result.
Summary

Using this functionality we can log the SQL commands that are generated and executed by Entity Framework. This feature can be used with only Entity Framework version 6.0 and above.