EF6 SQL Logging – Part 2: Changing the content/formatting | One Unicorn

In part 1 we saw how DbContext.Database.Log can be used to easily log SQL to the console or some other TextWriter. This post covers how the context and formatting of the output can be changed.

DatabaseLogFormatter

Under the covers the Database.Log property makes use of a DatabaseLogFormatter object. This object effectively binds a IDbCommandInterceptor implementation (see part 3 of this series) to a delegate that accepts strings and a DbContext. This means that interception methods on DatabaseLogFormatter are called before and after the execution of commands by EF. These DatabaseLogFormatter methods gather and format log output and send it to the delegate.

Changing what is logged and how it is formatted can be achieved by creating a new class that derives from DatabaseLogFormatter and then overriding methods as appropriate. The most common methods to override are:

  • LogCommand – Override this to change how commands are logged before they are executed. By default LogCommand calls LogParameter for each parameter; you may choose to do the same in your override or handle parameters differently instead.
  • LogResult – Override this to change how the outcome from executing a command is logged.
  • LogParameter – Override this to change the formatting and content of parameter logging.

For example, suppose we wanted to log just a single line before each command is sent to the database. This can be done with two overrides:

  • Override LogCommand to format and write the single line of SQL
  • Override LogResult to do nothing. (Executed could be overridden instead and this would probably be slightly more efficient, but functionally equivalent.)

The code would look something like this:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

public class OneLineFormatter : DatabaseLogFormatter

{

    public OneLineFormatter(DbContext context, Action<string> writeAction)

        : base(context, writeAction)

    {

    }

    public override void LogCommand<TResult>(

        DbCommand command, DbCommandInterceptionContext<TResult> interceptionContext)

    {

        Write(string.Format(

            "Context ‘{0}‘ is executing command ‘{1}‘{2}",

            Context.GetType().Name,

            command.CommandText.Replace(Environment.NewLine, ""),

            Environment.NewLine));

    }

    public override void LogResult<TResult>(

        DbCommand command, object result, DbCommandInterceptionContext<TResult> interceptionContext)

    {

    }

}

To log output simply call the Write method which will send output to the configured write delegate.

(Note that this code does simplistic removal of line breaks just as an example. It will likely not work well for viewing complex SQL.)

Setting the DatabaseLogFormatter

Once a new DatabaseLogFormatter class has been created it needs to be registered with EF. This is done using code-based configuration. In a nutshell this means creating a new class that derives from DbConfiguration in the same assembly as your DbContext class and then calling SetDatabaseLogFormatter in the constructor of this new class. For example:


1

2

3

4

5

6

7

8

public class MyDbConfiguration : DbConfiguration

{

    public MyDbConfiguration()

    {

        SetDatabaseLogFormatter(

            (context, writeAction) => new OneLineFormatter(context, writeAction));

    }

}

Using the new DatabaseLogFormatter

This new DatabaseLogFormatter will now be used anytime Database.Log is set. So, running the code from part 1 will now result in the following output:

Context ‘BlogContext‘ is executing command ‘SELECT TOP (1) [Extent1].[Id] AS [Id], [Extent1].[Title] AS [Title]FROM [dbo].[Blogs] AS [Extent1]WHERE (N‘One Unicorn‘ = [Extent1].[Title]) AND ([Extent1].[Title] IS NOT NULL)‘
Context ‘BlogContext‘ is executing command ‘SELECT [Extent1].[Id] AS [Id], [Extent1].[Title] AS [Title], [Extent1].[BlogId] AS [BlogId]FROM [dbo].[Posts] AS [Extent1]WHERE [Extent1].[BlogId] = @EntityKeyValue1‘
Context ‘BlogContext‘ is executing command ‘update [dbo].[Posts]set [Title] = @0where ([Id] = @1)‘
Context ‘BlogContext‘ is executing command ‘insert [dbo].[Posts]([Title], [BlogId])values (@0, @1)select [Id]from [dbo].[Posts]where @@rowcount > 0 and [Id] = scope_identity()‘

More control?

In the next post we’ll take a look at implementing IDbCommandInterceptor directly for even more control of command interception and show an example that integrates directly with NLog without using the Database.Log property.

转载:https://blog.oneunicorn.com/2013/05/09/ef6-sql-logging-part-2-changing-the-contentformatting/

来自为知笔记(Wiz)

时间: 2024-08-29 17:03:25

EF6 SQL Logging – Part 2: Changing the content/formatting | One Unicorn的相关文章

EF6 SQL Logging – Part 1: Simple Logging | One Unicorn

On the EF team we made a late decision to add some support for interception and logging of generated SQL in EF6. To this end recent checkins have added support for: A Log property for the context similar to DataContext.Log in LINQ to SQL A mechanism

EF6 SQL Logging – Part 3: Interception building blocks | One Unicorn

In parts 1 and 2 of this series we looked at how to use DbContext.Database.Log to log the SQL generated by EF. But this code is actually a relatively thin fa?ade over some low-level building blocks for interception in general and, in this case, DbCom

Spring/Hibernate Improved SQL Logging with log4jdbc---reference

Hibernate provides SQL logging out of the box, but such logging only shows prepared statements, and not the actual SQL queries sent to the database. It also does not log the execution time of each query, which is useful for performance troubleshootin

Entity Framework 6:专家版本

随着 Entity Framework 最新主版本 EF6 的推出,Microsoft 对象关系映射 (ORM) 工具达到了新的专业高度,与久负盛名的 .NET ORM 工具相比已不再是门外汉. EF 已经完全成熟,正在超越以前广泛使用的工具. Entity Framework 已经度过了青涩期,它最初只是供数据库开发者使用的工具,后来在 .NET 社区的敏捷开发者中间引起轰动. 它学会了如何摆脱应用程序开发模式,转向了普通旧 CLR 对象 (POCO) 模型,支持以测试和域为中心的软件开发,同

Logging and Intercepting Database Operations (EF6 Onwards)

Logging and Intercepting Database Operations Starting with Entity Framework 6, anytime Entity Framework sends a command to the database this command can be intercepted by application code. This is most commonly used for logging SQL, but can also be u

Confluence 6 SQL 异常的问题解决

如果你得到了与下面显示内容类似的信息话,那么你最好考虑修改 Confluence 的日志级别输出更多的信息.如果你考虑通过 Atlassian support 获得帮助,那么这些详细的错误信息能够更好的帮助我们找到问题的原因. 增加日志的级别将会让我们能够对下面的问题进行诊断: org.springframework.dao.DataIntegrityViolationException: (HibernateTemplate): data integrity violated by SQL '

PHP之防御sql注入攻击的方式

长期以来,web的安全性存在着巨大的争议与挑战.其中,sql注入就是一种常见的一种攻击方法,开发人员普遍的做法就是不停的过滤,转义参数,可是我们php大法天生弱类型的机制,总是让黑客有机可乘,绕过防御与防御总是在明争暗斗. 兄弟连(www.lampbrother.net )PHP大牛说过一句话,在一个程序中, 60% 的代码都应该是在进行各种防御. 其实,现在来看,防御sql注入其实并不需要进行各种参数过滤,以下将开启干货模式! PHP5.x开始引入了一种新的mysql操作方式-----mysq

PHP之防御sql注入攻击的方式 【兄弟连分享经验技巧】

长期以来,web的安全性存在着巨大的争议与挑战.其中,sql注入就是一种常见的一种攻击方法,开发人员普遍的做法就是不停的过滤,转义参数,可是我们php天生弱类型的机制,总是让黑客有机可乘,绕过防御与防御总是在明争暗斗. PHP大牛说过一句话,在一个程序中,60%的代码都应该是在进行各种防御. 其实,现在来看,防御sql注入其实并不需要进行各种参数过滤,以下将开启干货模式! PHP5.x开始引入了一种新的mysql操作方式-----mysqli,在php中也有一项相应的操作方式叫做PHP预处理.采

java用字符串拼接SQL语句的特殊字符转义问题

在实际的项目开发中,往往会根据用户在界面的文本框中输入的信息,去数据库中做模糊查询.如果使用的是原始的JDBC和SQL,往往需要对用户的输入进行转义,避免生成的sql语法错误,或者防止SQL注入.比如对输入的%和_和',就需要进行转义,因为这3个字符是SQL的特殊字符,如果不处理会导致sql出错或者是查询数据不正确. 假如有这样1个查询请求,模糊查询标题中包含a%b_cc'd的记录,正确的sql应该是下面这样的: select * from t_sch_work_info t where t.t