この記事は、Asp.Net Boilerplateテクノロジーを初めて使用し、データベースに関連する奇妙なエラーに遭遇した人向けに書かれています。 PostgreSQLを使用する場合、これは、たとえば、最初のプロジェクトです。 記事を書く動機は、英語でさえインターネット上でこの問題の解決策を見つけるのはそれほど簡単ではなく、見つかった解決策がこの問題に関するすべての質問に完全に答えないという事実は言うまでもないことでした。
製品バージョン:Asp.Net Boilerplate 4.3、.NET Core 2.1
次の手順に従う場合 :メインのログファイルには、データベースへのすべてのリクエストが記録されます。
ステップ1
ロガーを作成する必要があります。 Boilerplateプラットフォームには、構成済みの内部ロガーが既にあります。 標準でLog4Netにすることができます。 彼を操作する必要はありません。 代わりに、データベースからのすべてのログメッセージのハンドラーとして登録するロガークラスを作成します。
ステップ1.1
プロジェクト* .EntityFrameworkCore。 ここでは、2つのクラスを作成する必要があります。 一方では、たった1つのことを行うロガーは、データベースからシステムログにすべてのメッセージを出力します。 MyLoggerと呼びましょう。 そして、MyLoggerを作成するこのロガーのプロバイダー。 プロバイダーはMyLoggerProviderと呼ばれます。
次のコードで1つのファイルを作成します(簡単にするために1つのファイルを作成しますが、もちろん各ファイルには1つのクラスが必要です)。
public class MyLoggerProvider : ILoggerProvider { private Castle.Core.Logging.ILogger _logger; public MyLoggerProvider(Castle.Core.Logging.ILogger logger) { _logger = logger; } public ILogger CreateLogger(string categoryName) { return new MyLogger(_logger); } public void Dispose() { } } public class MyLogger : ILogger { private Castle.Core.Logging.ILogger _logger; public MyLogger(Castle.Core.Logging.ILogger logger) { _logger = logger; } public IDisposable BeginScope<TState>(TState state) { return null; } public bool IsEnabled(LogLevel logLevel) { return true; } public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter) { if (IsEnabled(logLevel)) { var msg = formatter(state, exception); _logger.Info("DB-REQUEST: " + msg); } } }
よく見ると、他のロガーがMyLoggerProviderに転送されてからMyLoggerに転送されていることがわかります。 すでに3番目が判明しています! 一番下の行は、この3番目がロギングインフラストラクチャレベルのクラスであり、メッセージをログに保存するためにボイラープレートの腸から取得する必要があるということです。 以下をご覧ください。
ステップ2
同じ* .EntityFrameworkCoreプロジェクトのフレームワーク内で、* DbContextConfigurer.csファイルに移動し、両方のConfigure()メソッドで次の変更を行います。
2.1)LoggerFactory型のloggerfactoryパラメーターを追加します
2.2)メソッド本体に2行追加します。
builder.UseLoggerFactory(loggerFactory); builder.EnableSensitiveDataLogging(true);
UseLoggerFactoryの意味は、データベースをログに記録するためのパラメーターで渡されるloggerFactoryの使用を有効にすることです。 ここでデータベースロギングを有効にすることに注意してください。
EnableSensitiveDataLoggingの意味は、データベースクエリのログを有効にするだけでなく、これらのクエリのすべてのデータを記録することです。 この設定がないと、クエリ内のデータを表示できません-それらは疑問符に置き換えられます。
ステップ3
同じ* .EntityFrameworkCoreプロジェクトのフレームワーク内で、* DbContextFactory.csファイルに移動します。
3.1)新しいメソッドを追加します:
private LoggerFactory GetDbLoggerFactory() { return new LoggerFactory(new[] { new MyLoggerProvider(NullLogger.Instance) }); }
3.2)CreateDbContext()メソッド内:
なぜなら 以前に両方のConfigure()実装に新しいパラメーターを追加したため、ここにエラーが表示されます。 この新しいパラメータを指定する時が来ました-GetDbLoggerFactory()をコンマで登録します。 つまり 新しいloggerFactoryパラメータの値は、3.1項の新しいメソッドによって返されます。
ステップ4
同じ* .EntityFrameworkCoreプロジェクトのフレームワーク内で、* EntityFrameworkModule.csファイルに移動します。
4.1)新しいメソッドを追加します:
private LoggerFactory GetDbLoggerFactory() { return new LoggerFactory(new[] { new MyLoggerProvider(Logger) }); }
4.2)PreInitialize()メソッドで:
なぜなら 以前に両方のConfigure()実装に新しいパラメーターを追加したため、ここにもエラーが表示されます。 セクション3.2のような新しいパラメーターを指定します-GetDbLoggerFactory()をコンマで登録します。 つまり 新しいloggerFactoryパラメーターの値は、4.1節の新しいメソッドによって返されます。
結果
メインログファイル(デフォルトではLogs.txt)には、「DB-REQUEST」という文字列が続くすべてのクエリが表示されます(ログ内のデータを検索できます)。
ソリューションの一般的な理解
それでは、私たちがやったことを説明しましょう。 説明は記事の最後に記載されています。 多くの場合、読者は既に特定の何かをすることに興味を持っています。
クラス* DbContextFactoryおよび* EntityFrameworkModuleで、作成したMyLoggerProviderを示すパラメーターでLoggerFactoryを作成します。 ただし、最初のケース(* DbContextFactory)で直接ログインするインフラストラクチャクラスとして、エントリがないようにNullLogger.Instanceスタブを渡します。 2番目のケース(* EntityFrameworkModule)では、ロガーを渡します。ロガーは既にAbpモジュールにあります。 これは、ロガーフィールドです。 これはすでに初期化されており、ログに記録できます。 したがって、MyLoggerはこのクラスを使用してLogs.txtファイルに書き込むことができます。
全体的なロジックは、このloggerFactoryファクトリがデータベースを操作するためのログファクトリとしてインストールされることです。 ロガーが必要になるとすぐに、工場で作成されます。 これがMyLoggerであり、Logs.txt(またはメインログの出力が構成されているソース)に送信されるすべてのものを順に記録します。
ご覧のとおり、すべてがそれほど単純ではなく、特に初心者の場合、抽象化のレベルがフリーズすることがあります! コメントで質問してください。
注:
-ソリューションは、ロガーをオンにし、エラーの内容を理解してオフにするために作成されました。 長期間使用するようには設計されていません。