Entity Framework Core Series Tutorial-25-Entity Framework Core Log

Entity Framework Core logs

We often need to record SQL in EF Core and change trace information for debugging.
EF Core logging is automatically integrated with the logging mechanism of .NET Core. Therefore, before implicitly using EF Core's logging, understand the basics about .NET Core logging.
Entity Framework Core is integrated with .NET Core logging to record SQL and change trace information to various output targets. First, install the Nuget package of the logging provider of your choice, and then bind the DbContext to the ILoggerFactory.
Let's install the NuGet package of the logging provider. Here, we will display the logs on the console, so install the Microsoft.Extensions.Logging.Console NuGet package from the NuGet package manager, or execute the following command in the package manager console:

Install-Package Microsoft.Extensions.Logging.Console

The following diagram illustrates how DbContext is used with the logging API and console logging provider.
[External chain image transfer failed, the source site may have an anti-theft chain mechanism, it is recommended to save the image and upload it directly (img-afUjJAU3-1581165281344) (d: \ note \ efcore \ pic \ 27.png)]

After installing the console logger provider, you need to create a static / single instance of LoggerFactory and then bind it with DbContext as shown below.

public class SchoolContext : DbContext
{
    //static LoggerFactory object
    public static readonly ILoggerFactory loggerFactory = new LoggerFactory(new[] {
              new ConsoleLoggerProvider((_, __) => true, true)
        });

    //or
    // public static readonly ILoggerFactory loggerFactory  = new LoggerFactory().AddConsole((_,___) => true);
    
    public SchoolContext():base()
    {

    }
    
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseLoggerFactory(loggerFactory)  //tie-up DbContext with LoggerFactory object
            .EnableSensitiveDataLogging()  
            .UseSqlServer(@"Server=.\SQLEXPRESS;Database=SchoolDB;Trusted_Connection=True;");
    }
        
    public DbSet<Student> Students { get; set; }
}

In the above example, we created an object of the LoggerFactory class and assigned it to a static variable of type ILoggerFactory. Then, we passed this object in the optionsBuilder.UseLoggerFactory () method of the OnConfiguring () method. This will enable DbContext to share information with the loggerFactory object, which in turn will display all logging information on the console.
By default, EF Core will not record sensitive data, such as filter parameter values. Therefore, call EnableSensitiveDataLogging () to record sensitive data.
Note: The
EF team recommends using the same logger factory object with all instances of the DbContext class during the lifetime of the application. Otherwise, it may cause memory leaks and performance degradation. You can also create a separate factory class that provides you with a singleton object of the LoggerFactory class for use with DbContext.
Let us understand the above example in detail.
First, we created an object of the LoggerFactory class and assigned it to a static variable of type ILoggerFactory, as shown below.

public static readonly ILoggerFactory loggerFactory = new LoggerFactory(
    new[] { new ConsoleLoggerProvider ((_, __) => true, true) }
);

LoggerFactory can contain one or more log record providers, which can be used to record to multiple media at the same time. The constructor of LoggerFactory accepts a series of different logger provider objects as new [] {}. We want to display the log on the console, so create an object for the console logger provider ConsoleLoggerProvider.
ConsoleLoggerProvider has four constructors. Use a method that allows lambda expressions (Func <>) for log filtering, and use includeScope boolean, as shown below.

new ConsoleLoggerProvider((_, __) => true, true)

Here, we don't want to filter any information, so the lambda expression will always return true (_, __) => true.

After creating the ILoggerFactory object, use DbContextOptionsBuilder to bind DbContext and ILoggerFactory together in the OnConfiguring () method.

optionsBuilder.UseLoggerFactory(loggerFactory)

Therefore, we bind the DbContext to the LoggerFactory that includes the console logger provider. Now, whenever the DbContext instance performs any operation, we can see all the logs on the console.
Consider the following example.

using (var context = new SchoolContext())
{
    var std = new Student(){ StudentName = "Steve" };
    context.Add(std);
                
    context.SaveChanges();
    Console.ReadLine();
}

The above example will display the following logs on the console:

dbug: Microsoft.EntityFrameworkCore.Infrastructure[100401]
An 'IServiceProvider' was created for internal use by Entity Framework.
info: Microsoft.EntityFrameworkCore.Infrastructure[100403]
Entity Framework Core 2.0.0-rtm-26452 initialized 'SchoolContext' using pr
ovider 'Microsoft.EntityFrameworkCore.SqlServer' with options: SensitiveDataLoggingEnabled
dbug: Microsoft.EntityFrameworkCore.Database.Connection[200000]
Opening connection to database 'SchoolDB' on server '.\SQLEXPRESS'.

dbug: Microsoft.EntityFrameworkCore.Database.Connection[200001]
Opened connection to database 'SchoolDB' on server '.\SQLEXPRESS'.
dbug: Microsoft.EntityFrameworkCore.Database.Transaction[200200]
Beginning transaction with isolation level 'ReadCommitted'.
warn: Microsoft.EntityFrameworkCore.Database.Command[100400]
Sensitive data logging is enabled. Log entries and exception messages may
include sensitive application data, this mode should only be enabled during development.
dbug: Microsoft.EntityFrameworkCore.Database.Command[200100]
Executing DbCommand [Parameters=[@p0='' (DbType = DateTime2), @p1='' (DbTy
pe = Int32), @p2='0', @p3='' (Size = 8000) (DbType = Binary), @p4='Steve' (Size = 4000), @p5='0'], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
INSERT INTO [Students] ([DateOfBirth], [GradeId], [Height], [Photo], [Stud
entName], [Weight])
VALUES (@p0, @p1, @p2, @p3, @p4, @p5);
SELECT [StudentID]
FROM [Students]
WHERE @@ROWCOUNT = 1 AND [StudentID] = scope_identity();
info: Microsoft.EntityFrameworkCore.Database.Command[200101]
Executed DbCommand (68ms) [Parameters=[@p0='' (DbType = DateTime2), @p1=''
(DbType = Int32), @p2='0', @p3='' (Size = 8000) (DbType = Binary), @p4='Steve'
(Size = 4000), @p5='0'], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
INSERT INTO [Students] ([DateOfBirth], [GradeId], [Height], [Photo], [Stud
entName], [Weight])
VALUES (@p0, @p1, @p2, @p3, @p4, @p5);
SELECT [StudentID]
FROM [Students]
WHERE @@ROWCOUNT = 1 AND [StudentID] = scope_identity();
dbug: Microsoft.EntityFrameworkCore.Database.Command[200300]
A data reader was disposed.
dbug: Microsoft.EntityFrameworkCore.Database.Transaction[200202]
Committing transaction.
dbug: Microsoft.EntityFrameworkCore.Database.Connection[200002]
Closing connection to database 'SchoolDB' on server '.\SQLEXPRESS'.

dbug: Microsoft.EntityFrameworkCore.Database.Connection[200003]
Closed connection to database 'SchoolDB' on server '.\SQLEXPRESS'.
dbug: Microsoft.EntityFrameworkCore.Database.Transaction[200204]
Disposing transaction.

As you can see, it records all the information.

Filter logs

In the above example, DbContext records all information when saving the entity. Sometimes you do n’t want to record all the information and filter some unwanted logs. In EF Core, you can filter logs by specifying the logger category and log level.

Log classification

EF Core 2.x includes the DbLoggerCategory class to obtain the Entity Framework Core logger category using its Name property. The following table lists the different logger categories.

Log category description
Database.Command The type of logger the command executes, including the SQL sent to the database.
Database.Connection The logger category for database connection operations.
Database.Transaction The logger category for database transactions.
Infrastructure Recorder category for other messages in the EF infrastructure.
Migration Migrated logger category.
Model The logger category used for model building and metadata.
Query The logger category of the query (excluding the generated SQL).
Scaffolding Types of recorders for scaffolding and reverse engineering.
Update The logger category of DbContext.SaveChanges () message.

Log SQL queries

To log only SQL queries, specify the DbLoggerCategory.Database.Command category and LogLevel.Information in the lambda expression of the ConsoleLoggerProvider constructor, as shown below.

public static readonly ILoggerFactory consoleLoggerFactory  
            = new LoggerFactory(new[] {
                  new ConsoleLoggerProvider((category, level) =>
                    category == DbLoggerCategory.Database.Command.Name &&
                    level == LogLevel.Information, true)
                });

Or, by default, just call the AddConsole () method on the LoggerFactory to log SQL queries.

public static readonly ILoggerFactory consoleLoggerFactory
         = new LoggerFactory().AddConsole();

Now, this will record the following query information, which uses DbContext to save an entity.

info: Microsoft.EntityFrameworkCore.Database.Command[200101]
Executed DbCommand (73ms) [Parameters=[@p0='' (DbType = DateTime2), @p1=''
(DbType = Int32), @p2='0', @p3='' (Size = 8000) (DbType = Binary), @p4='Steve'
(Size = 4000), @p5='0'], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
INSERT INTO [Students] ([DateOfBirth], [GradeId], [Height], [Photo], [Stud
entName], [Weight])
VALUES (@p0, @p1, @p2, @p3, @p4, @p5);
SELECT [StudentID]
FROM [Students]
WHERE @@ROWCOUNT = 1 AND [StudentID] = scope_identity();
Published 177 original articles · 61 praises · 170,000 views

Guess you like

Origin blog.csdn.net/xingkongtianyuzhao/article/details/104227989