Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Tips/Råd
Du kan ladda ned den här artikelns exempel från GitHub.
Enkel loggning med Entity Framework Core (EF Core) kan användas för att enkelt hämta loggar när du utvecklar och felsöker program. Den här typen av loggning kräver minimal konfiguration och inga ytterligare NuGet-paket.
Tips/Råd
EF Core integreras också med Microsoft.Extensions.Logging, som kräver mer konfiguration, men som ofta är lämpligare för loggning i produktionsprogram.
Konfiguration
EF Core-loggar kan nås från alla typer av program med hjälp av LogTo när du konfigurerar en DbContext-instans. Den här konfigurationen görs ofta i en åsidosättning av DbContext.OnConfiguring. Till exempel:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder.LogTo(Console.WriteLine);
Alternativt kan LogTo anropas som en del av AddDbContext eller när du skapar en DbContextOptions-instans som ska skickas till DbContext-konstruktorn.
Tips/Råd
OnConfiguring anropas fortfarande när AddDbContext används eller en DbContextOptions-instans skickas till DbContext-konstruktorn. Detta gör det till den perfekta platsen för att tillämpa kontextkonfiguration oavsett hur DbContext konstrueras.
Dirigera loggarna
Logga in på konsolen
              LogTo kräver en Action<T> delegerad som tar emot en sträng. EF Core anropar det här ombudet med en sträng för varje loggmeddelande som genereras. Det är sedan upp till ombudet att göra något med det angivna meddelandet.
Metoden Console.WriteLine används ofta för det här ombudet, som du ser ovan. Detta resulterar i att varje loggmeddelande skrivs till konsolen.
Logga till felsökningsfönstret
              Debug.WriteLine kan användas för att skicka utdata till felsökningsfönstret i Visual Studio eller andra IDE:er. 
              Lambda-syntax måste användas i det här fallet eftersom Debug klassen kompileras från versionsversioner. Till exempel:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder.LogTo(message => Debug.WriteLine(message));
Logga in på en fil
Att skriva till en fil kräver att du skapar en StreamWriter eller liknande för filen. Metoden WriteLine kan sedan användas som i de andra exemplen ovan. Kom ihåg att se till att filen stängs korrekt genom att ta bort skrivaren när kontexten tas bort. Till exempel:
private readonly StreamWriter _logStream = new StreamWriter("mylog.txt", append: true);
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder.LogTo(_logStream.WriteLine);
public override void Dispose()
{
    base.Dispose();
    _logStream.Dispose();
}
public override async ValueTask DisposeAsync()
{
    await base.DisposeAsync();
    await _logStream.DisposeAsync();
}
Tips/Råd
Överväg att använda Microsoft.Extensions.Logging för loggning till filer i produktionsprogram.
Få detaljerade meddelanden
Känsliga data
Som standard innehåller EF Core inte värdena för några data i undantagsmeddelanden. Detta beror på att sådana data kan vara konfidentiella och kan avslöjas i produktionsanvändning om ett undantag inte hanteras.
Men att känna till datavärden, särskilt för nycklar, kan vara till stor hjälp vid felsökning. Detta kan aktiveras i EF Core genom att anropa EnableSensitiveDataLogging(). Till exempel:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .LogTo(Console.WriteLine)
        .EnableSensitiveDataLogging();
Detaljerade frågeundantag
Av prestandaskäl omsluter EF Core inte varje anrop för att läsa ett värde från databasprovidern i ett try-catch-block. Detta resulterar dock ibland i undantag som är svåra att diagnostisera, särskilt när databasen returnerar en NULL när den inte tillåts av modellen.
Att slå på EnableDetailedErrors gör att EF introducerar dessa try-catch-block och därigenom ger mer detaljerade fel. Till exempel:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .LogTo(Console.WriteLine)
        .EnableDetailedErrors();
Filtrering
Loggnivåer
Varje EF Core-loggmeddelande tilldelas en nivå som definieras av uppräkningen LogLevel. Som standardinställning innehåller EF Core enkel loggning varje meddelande på Debug-nivå eller högre. 
              LogTo kan ha en högre minimumnivå för att filtrera bort vissa meddelanden. Om du till exempel skickar Information resulterar det i en minimal uppsättning loggar som är begränsade till databasåtkomst och vissa hushållningsmeddelanden.
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder.LogTo(Console.WriteLine, LogLevel.Information);
Specifika meddelanden
Varje loggmeddelande tilldelas en EventId. Dessa ID:er kan nås från CoreEventId klassen eller RelationalEventId klassen för relationsspecifika meddelanden. En databasprovider kan också ha providerspecifika ID:er i en liknande klass. Till exempel SqlServerEventId för SQL Server-providern.
              LogTo kan konfigureras för att endast logga de meddelanden som är associerade med ett eller flera händelse-ID:t. Om du till exempel bara vill logga meddelanden för den kontext som initieras eller tas bort:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .LogTo(Console.WriteLine, new[] { CoreEventId.ContextDisposed, CoreEventId.ContextInitialized });
Meddelandekategorier
Varje loggmeddelande tilldelas till en namngiven hierarkisk loggningskategori. Kategorierna är:
| Kategori | Meddelanden | 
|---|---|
| Microsoft.EntityFrameworkCore | Alla EF Core-meddelanden | 
| Microsoft.EntityFrameworkCore.Database | Alla databasinteraktioner | 
| Microsoft.EntityFrameworkCore.Database.Connection | Användning av en databasanslutning | 
| Microsoft.EntityFrameworkCore.Database.Command | Användning av ett databaskommando | 
| Microsoft.EntityFrameworkCore.Database.Transaction | Användning av en databastransaktion | 
| Microsoft.EntityFrameworkCore.Update | Spara objekt, utan databasinteraktioner | 
| Microsoft.EntityFrameworkCore.Model | Alla modell- och metadatainteraktioner | 
| Microsoft.EntityFrameworkCore.Model.Validation | Modellverifiering | 
| Microsoft.EntityFrameworkCore.Query | Frågor, exklusive databasinteraktioner | 
| Microsoft.EntityFrameworkCore.Infrastructure | Allmänna händelser, till exempel skapande av kontext | 
| Microsoft.EntityFrameworkCore.Scaffolding | Omvänd databasteknik | 
| Microsoft.EntityFrameworkCore.Migrations | Migreringar | 
| Microsoft.EntityFrameworkCore.ChangeTracking | Interaktioner med ändringsspårning | 
              LogTo kan konfigureras för att endast logga meddelanden från en eller flera kategorier. Om du till exempel bara vill logga databasinteraktioner:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .LogTo(Console.WriteLine, new[] { DbLoggerCategory.Database.Name });
Observera att DbLoggerCategory klassen tillhandahåller ett hierarkiskt API för att hitta en kategori och undviker behovet av hårdkodade strängar.
Eftersom kategorier är hierarkiska innehåller det här exemplet med Database kategorin alla meddelanden för underkategorierna Database.Connection, Database.Commandoch Database.Transaction.
Anpassade filter
              LogTo tillåter att ett anpassat filter används för fall där inget av filtreringsalternativen ovan räcker. Om du till exempel vill logga ett meddelande på nivå Information eller högre, samt meddelanden för att öppna och stänga en anslutning:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .LogTo(
            Console.WriteLine,
            (eventId, logLevel) => logLevel >= LogLevel.Information
                                   || eventId == RelationalEventId.ConnectionOpened
                                   || eventId == RelationalEventId.ConnectionClosed);
Tips/Råd
Att använda anpassade filter eller något av de andra alternativ som visas här är mer effektivt än att filtrera i delegeraren LogTo. Det beror på att om filtret bestämmer att meddelandet inte ska loggas skapas inte loggmeddelandet ens.
Konfiguration för specifika meddelanden
MED EF Core ConfigureWarnings API kan program ändra vad som händer när en specifik händelse påträffas. Detta kan användas för att:
- Ändra loggnivån där händelsen loggas
- Hoppa över att logga händelsen helt och hållet
- Utlöser ett undantag när händelsen inträffar
Ändra loggnivån för en händelse
I föregående exempel användes ett anpassat filter för att logga varje meddelande vid LogLevel.Information samt två händelser som definierats för LogLevel.Debug. Samma sak kan uppnås genom att ändra loggnivån för de två Debug händelserna till Information:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .ConfigureWarnings(
            b => b.Log(
                (RelationalEventId.ConnectionOpened, LogLevel.Information),
                (RelationalEventId.ConnectionClosed, LogLevel.Information)))
        .LogTo(Console.WriteLine, LogLevel.Information);
Förhindra loggning av en händelse
På liknande sätt kan en enskild händelse förhindras från loggning. Detta är särskilt användbart för att ignorera en varning som har granskats och förståtts. Till exempel:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .ConfigureWarnings(b => b.Ignore(CoreEventId.DetachedLazyLoadingWarning))
        .LogTo(Console.WriteLine);
Anordna ett evenemang
Slutligen kan EF Core konfigureras för att generera för en viss händelse. Detta är särskilt användbart för att ändra en varning till ett fel. (Detta var faktiskt det ursprungliga syftet med ConfigureWarnings metoden, därav namnet.) Till exempel:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .ConfigureWarnings(b => b.Throw(RelationalEventId.MultipleCollectionIncludeWarning))
        .LogTo(Console.WriteLine);
Meddelandeinnehåll och formatering
Standardinnehållet från LogTo formateras över flera rader. Den första raden innehåller meddelandemetadata:
- Prefixet LogLevel med fyra tecken
- En lokal tidsstämpel, formaterad för den aktuella kulturen
- I EventId formuläret som kan kopieras/klistras in för att få tag på medlemmen från CoreEventId eller någon av de andra EventIdklasserna, plus det ursprungliga ID-värdet
- Händelsekategorin enligt beskrivningen ovan.
Till exempel:
info: 10/6/2020 10:52:45.581 RelationalEventId.CommandExecuted[20101] (Microsoft.EntityFrameworkCore.Database.Command)
      Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      CREATE TABLE "Blogs" (
          "Id" INTEGER NOT NULL CONSTRAINT "PK_Blogs" PRIMARY KEY AUTOINCREMENT,
          "Name" INTEGER NOT NULL
      );
dbug: 10/6/2020 10:52:45.582 RelationalEventId.TransactionCommitting[20210] (Microsoft.EntityFrameworkCore.Database.Transaction)
      Committing transaction.
dbug: 10/6/2020 10:52:45.585 RelationalEventId.TransactionCommitted[20202] (Microsoft.EntityFrameworkCore.Database.Transaction)
      Committed transaction.
Det här innehållet kan anpassas genom att skicka värden från DbContextLoggerOptions, som du ser i följande avsnitt.
Tips/Råd
Överväg att använda Microsoft.Extensions.Logging för mer kontroll över loggformatering.
Använda UTC-tid
Som standard är tidsstämplar utformade för lokal förbrukning vid felsökning. Använd DbContextLoggerOptions.DefaultWithUtcTime för att använda kulturagnostiska UTC-tidsstämplar i stället, men behåll allt annat på samma sätt. Till exempel:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder.LogTo(
        Console.WriteLine,
        LogLevel.Debug,
        DbContextLoggerOptions.DefaultWithUtcTime);
Det här exemplet resulterar i följande loggformatering:
info: 2020-10-06T17:55:39.0333701Z RelationalEventId.CommandExecuted[20101] (Microsoft.EntityFrameworkCore.Database.Command)
      Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      CREATE TABLE "Blogs" (
          "Id" INTEGER NOT NULL CONSTRAINT "PK_Blogs" PRIMARY KEY AUTOINCREMENT,
          "Name" INTEGER NOT NULL
      );
dbug: 2020-10-06T17:55:39.0333892Z RelationalEventId.TransactionCommitting[20210] (Microsoft.EntityFrameworkCore.Database.Transaction)
      Committing transaction.
dbug: 2020-10-06T17:55:39.0351684Z RelationalEventId.TransactionCommitted[20202] (Microsoft.EntityFrameworkCore.Database.Transaction)
      Committed transaction.
Loggning med en rad
Ibland är det bra att få exakt en rad per loggmeddelande. Detta kan aktiveras av DbContextLoggerOptions.SingleLine. Till exempel:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder.LogTo(
        Console.WriteLine,
        LogLevel.Debug,
        DbContextLoggerOptions.DefaultWithLocalTime | DbContextLoggerOptions.SingleLine);
Det här exemplet resulterar i följande loggformatering:
info: 10/6/2020 10:52:45.723 RelationalEventId.CommandExecuted[20101] (Microsoft.EntityFrameworkCore.Database.Command) -> Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30']CREATE TABLE "Blogs" (    "Id" INTEGER NOT NULL CONSTRAINT "PK_Blogs" PRIMARY KEY AUTOINCREMENT,    "Name" INTEGER NOT NULL);
dbug: 10/6/2020 10:52:45.723 RelationalEventId.TransactionCommitting[20210] (Microsoft.EntityFrameworkCore.Database.Transaction) -> Committing transaction.
dbug: 10/6/2020 10:52:45.725 RelationalEventId.TransactionCommitted[20202] (Microsoft.EntityFrameworkCore.Database.Transaction) -> Committed transaction.
Andra innehållsalternativ
Andra flaggor i DbContextLoggerOptions kan användas för att minska mängden metadata som ingår i loggen. Detta kan vara användbart i kombination med loggning av enstaka rader. Till exempel:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder.LogTo(
        Console.WriteLine,
        LogLevel.Debug,
        DbContextLoggerOptions.UtcTime | DbContextLoggerOptions.SingleLine);
Det här exemplet resulterar i följande loggformatering:
2020-10-06T17:52:45.7320362Z -> Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30']CREATE TABLE "Blogs" (    "Id" INTEGER NOT NULL CONSTRAINT "PK_Blogs" PRIMARY KEY AUTOINCREMENT,    "Name" INTEGER NOT NULL);
2020-10-06T17:52:45.7320531Z -> Committing transaction.
2020-10-06T17:52:45.7339441Z -> Committed transaction.
Övergång från EF6
Enkel EF Core-loggning skiljer sig från Database.Log i EF6 på två viktiga sätt:
- Loggmeddelanden är inte begränsade till endast databasinteraktioner
- Loggningen måste konfigureras vid tidpunkten för kontextinitiering
För den första skillnaden kan filtreringen som beskrivs ovan användas för att begränsa vilka meddelanden som loggas.
Den andra skillnaden är en avsiktlig ändring för att förbättra prestanda genom att inte generera loggmeddelanden när de inte behövs. Det går dock fortfarande att få ett liknande beteende som EF6 genom att skapa en Log egenskap på din DbContext och sedan bara använda den när den har angetts. Till exempel:
public Action<string> Log { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder.LogTo(s => Log?.Invoke(s));