ご挨拶!
プログラミングに関する一連の記事を続けます。 今回は、Entity Framework(以下EFと呼びます)のために第4版から第6版まで書いた無料のプロファイラーと、.NETコードをその場で逆コンパイルするなど、私が適用したいくつかのソリューションについてお話したいと思います例外処理など。
EF6のNugetパッケージ: https ://www.nuget.org/packages/EFlogger-For6/
EF4-5のNugetパッケージ: https ://www.nuget.org/packages/EFlogger-For4/
カットの下の詳細。
はじめに
EFの学習を開始したとき、EFが生成するクエリのプロファイリングについて質問がありました。 いくつかの検索の後、EFが通常のツールを提供していないことに気がつき、
EFバージョン6の登場により、コマンドロギングの状況が変わりました。 独自のインターセプターを追加できるメカニズムが登場しました。
// IDbCommandInterceptor DbInterception.Add(new LogFormatter());
public class LogFormatter : IDbCommandInterceptor { private readonly Stopwatch _stopwatch = new Stopwatch(); public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext) { // _stopwatch.Restart(); } public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext) { // _stopwatch.Stop(); // Log(command, interceptionContext); } public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext) { _stopwatch.Restart(); } public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext) { _stopwatch.Stop(); Log(command, interceptionContext); } public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext) { _stopwatch.Restart(); } public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext) { _stopwatch.Stop(); Log(command, interceptionContext); } private void Log<TResult>(DbCommand command, DbCommandInterceptionContext<TResult> interceptionContext) { Logger.Log(command, _stopwatch.ElapsedMilliseconds, interceptionContext.Exception); } }
public static class Logger { public static void Log(DbCommand command, long elapsedMilliseconds, Exception exception) { // Trace Trace.WriteLine(string.Format("Command:{0}, Elapsed Milliseconds:{1}", command.CommandText, elapsedMilliseconds)); } }
EFの4番目のバージョンでは、同様のログメカニズムは見つかりませんでした。
私の決断
プロファイラーを作成し、有料のプロファイラーの機能を繰り返すというアイディアは、かなり前から持ち歩いています。 初期バージョンはEFバージョン6インターセプターメカニズムに基づいていましたが、残念ながらEFバージョン4ではこのメカニズムは機能しません。
短いグーグル検索の後、ASP MVCアプリケーションでEFをプロファイリングするための、 MiniProfilerと呼ばれるすばらしいライブラリが見つかりました。 それに基づいて、アプリケーションを作成することが決定されました。
どうした
システムは、使用および統合が可能な限りシンプルであることが判明しました。 wordpress-e http://ef-logger.com/で作成したサイトのサンプルプロジェクトでバイナリを取得できます。
EF6のNugetパッケージ: https ://www.nuget.org/packages/EFlogger-For6/
メインアプリケーションウィンドウ:
使用する
1. バイナリとサンプルプロジェクトを含むアーカイブを取得する
2. EF 4-5バージョンの場合はライブラリEFlogger.EntityFramework4.dllを、EF 6thバージョンの場合はEFlogger.EntityFramework6.dllを接続します
3.静的メソッドを実行してプロファイラーを初期化します
// EF 6- EFloggerFor6.Initialize(); // EF 4- 6- EFloggerFor4.Initialize();
4. EFlogger.exeアプリケーションを起動します
API
EFlogger.EntityFramework6.dlライブラリの例。EFlogger.EntityFramework4.dlを使用する場合、静的クラスはEFloggerFor4と呼ばれます
// EFloggerFor6.Initialize(); // IP "127.0.0.1" EFloggerFor6.SetProfilerClientIP(“192.168.10.50″); // EFloggerFor6.WriteMessage(“Text message”); // ( ) EFloggerFor6.StartSendToClient(); // EFloggerFor6.StopSendToClient(); // EFlogger.log EFloggerFor6.StartSaveToLogFile(); // EFlogger.log EFloggerFor6.StopSaveToLogFile(); // , EFloggerFor6.ClearLog(); // EFloggerFor6.DisableDecompiling(); // Stack Trace-a EFloggerFor6.ExcludeAssembly(“MyAssemly”);
すべての仕組み
EF 4thバージョンの実装メカニズムは、EF 6thバージョンとは大きく異なります。
EF 4のDbProviderFactoryを置き換えるための通常のメカニズムはないため、リフレクションを使用してファクトリを独自のファクトリに置き換える必要があります。
プロセス自体は次のようになります。
// DbProviderFactories.GetFactoryClasses(); // DbProviderFactories Type type = typeof(DbProviderFactories); DataTable table = null; // DataSet _configTable _providerTable object setOrTable = (type.GetField("_configTable", BindingFlags.NonPublic | BindingFlags.Static) ?? type.GetField("_providerTable", BindingFlags.NonPublic | BindingFlags.Static)).GetValue(null); var set = setOrTable as DataSet; if (set != null) table = set.Tables["DbProviderFactories"]; table = (DataTable)setOrTable; // DataTable foreach (DataRow row in table.Rows.Cast<DataRow>().ToList()) { DbProviderFactory factory; try { factory = DbProviderFactories.GetFactory(row); } catch (Exception) { continue; } var profType = EFProviderUtilities.ResolveFactoryType(factory.GetType()); if (profType != null) { DataRow profiled = table.NewRow(); profiled["Name"] = row["Name"]; profiled["Description"] = row["Description"]; profiled["InvariantName"] = row["InvariantName"]; profiled["AssemblyQualifiedName"] = profType.AssemblyQualifiedName; table.Rows.Remove(row); table.Rows.Add(profiled); } }
EF 6thバージョンへの統合については、サービスを置き換えるための通常のメカニズムを使用できます。
DbConfiguration.Loaded += (_, a) => a.ReplaceService<DbProviderServices>((s, k) => new EFProfiledDbProviderServices());
逆コンパイル
EFloggerはコードを逆コンパイルし、この要求またはその要求を生成したメソッドの本体を表示します。 このために、 ILSpyリフレクターの無料のアナログのライブラリが使用されます。 メソッドを逆コンパイルするには、最初にStack Traceを起動して、サードパーティライブラリへの不要な呼び出しを排除することにより、それを見つける必要があります。
public static string Get(out StackFrame outStackFrame) { outStackFrame = null; var frames = new StackTrace(0, true).GetFrames(); if (frames == null) { return ""; } var methods = new List<string>(); // foreach (StackFrame t in frames) { // var method = t.GetMethod(); // var assembly = method.Module.Assembly.GetName().Name; if (ShouldExcludeType(method) || AssembliesToExclude.Contains(assembly) || MethodsToExclude.Contains(method.Name)) continue; // , if (outStackFrame == null) { outStackFrame = t; } methods.Add(method.DeclaringType.FullName + ":" + method.Name); } return string.Join("\r\n", methods); }
private static string GetMethodBody(StackFrame stackFrame) { MethodBase methodBase = stackFrame.GetMethod(); return Decompiler.GetSourceCode(methodBase.Module.FullyQualifiedName, methodBase.DeclaringType.Name, methodBase.Name); }
逆コンパイラ
using System; using System.IO; using System.Linq; using ICSharpCode.Decompiler; using ICSharpCode.Decompiler.Ast; using ICSharpCode.Decompiler.Ast.Transforms; using Mono.Cecil; namespace Common { public static class Decompiler { public static string GetSourceCode(string pathToAssembly, string className, string methodName) { try { var assemblyDefinition = AssemblyDefinition.ReadAssembly(pathToAssembly); TypeDefinition assembleDefenition = assemblyDefinition.MainModule.Types.First(type => type.Name == className); MethodDefinition methodDefinition = assembleDefenition.Methods.First(method => method.Name == methodName); var output = new StringWriter(); var plainTextOutput = new PlainTextOutput(output); DecompileMethod(methodDefinition, plainTextOutput); return output.ToString(); } catch (Exception exception) { return string.Format( "Exception in decompling. \r\n Message:{0}, \r\n Inner Exception:{1}, \r\n StackTrace:{2}",exception.Message, exception.InnerException, exception.StackTrace); } } private static void DecompileMethod(MethodDefinition method, ITextOutput output) { AstBuilder codeDomBuilder = CreateAstBuilder(currentType: method.DeclaringType, isSingleMember: true); if (method.IsConstructor && !method.IsStatic && !method.DeclaringType.IsValueType) { AddFieldsAndCtors(codeDomBuilder, method.DeclaringType, method.IsStatic); RunTransformsAndGenerateCode(codeDomBuilder, output); } else { codeDomBuilder.AddMethod(method); RunTransformsAndGenerateCode(codeDomBuilder, output); } } private static AstBuilder CreateAstBuilder(ModuleDefinition currentModule = null, TypeDefinition currentType = null, bool isSingleMember = false) { if (currentModule == null) currentModule = currentType.Module; var settings = new DecompilerSettings(); if (isSingleMember) { settings = settings.Clone(); settings.UsingDeclarations = false; } return new AstBuilder( new DecompilerContext(currentModule) { CurrentType = currentType, Settings = settings }); } private static void AddFieldsAndCtors(AstBuilder codeDomBuilder, TypeDefinition declaringType, bool isStatic) { foreach (var field in declaringType.Fields) { if (field.IsStatic == isStatic) codeDomBuilder.AddField(field); } foreach (var ctor in declaringType.Methods) { if (ctor.IsConstructor && ctor.IsStatic == isStatic) codeDomBuilder.AddMethod(ctor); } } private static void RunTransformsAndGenerateCode(AstBuilder astBuilder, ITextOutput output, IAstTransform additionalTransform = null) { astBuilder.GenerateCode(output); } } }
Yandexファイルで動作する逆コンパイルプロジェクトの例: yadi.sk/d/AzBGet5-Nwns2
例外処理ウィンドウ
アプリケーションが定期的にクラッシュすることは秘密ではありません。これはさまざまな理由で発生する可能性があります。開発者のタスクは、エラーメッセージに対して何らかの健全なウィンドウを表示することです。
私のフォームバリアントは次のようになります。
このフォームは、エラー、再現手順、および応答する電子メールに関する情報を追加するようユーザーに求めます。
[送信]ボタンをクリックすると、すべてのデータが記載されたレターが開発者にメールで送信されます。
[STAThread] [STAThread] static void Main() { SetupLogger(); // if (!Debugger.IsAttached) { // Application.ThreadException += (sender, e) => HandleError(e.Exception); AppDomain.CurrentDomain.UnhandledException += (sender, e) => HandleError((Exception)e.ExceptionObject); } Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MainForm()); } private static void HandleError(Exception exception) { try { // try/catch new ErrorHandlerController(exception).Run(); } catch (Exception e) { MessageBox.Show("Error processing exception. Please send log file EFlogger.log to developer: " + Settings.Default.ProgrammerEmail + " \r\n Exception:" + e); // Logger.Error(e); if (MessageBox.Show("Attach debugger? \n Only for developer!!!", "Debugging...", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { Debugger.Launch(); throw; } } finally { // Windows Environment.Exit(1); } } //new ErrorHandlerController(exception).Run(); public void Run() { // string exceptionInfoText = string.Format( "An unexpected error occurred: {0}" + Environment.NewLine + "Time: {1} " + Environment.NewLine + "{2}" + Environment.NewLine + "InnerException: \n {3}" + Environment.NewLine + "InnerException StackTrace: \n {4}" + Environment.NewLine, _exception.Message, DateTime.Now, _exception, _exception.InnerException, _exception.InnerException != null ? _exception.InnerException.StackTrace : string.Empty ); // Program.Logger.Error(exceptionInfoText); _view.ExceptionInfoText = exceptionInfoText; // , ShowDialog, _view.ShowDialog(); }
エラー処理フォームを含む作業ドラフトの例は、Yandexファイルにあります: yadi.sk/d/7y4i_cz7NwtE3
ネットワーク接続
プラグインライブラリとプロファイラーの間のネットワーク相互作用の詳細については、以前の記事「 CでのTCPによるネットワーク通信#
ちょっとしたユーモア
友人の
リクエスト
コマンドテキスト:
選択 [Project238]。[C4] AS [C1]、 [Project238]。[Name] AS [Name]、 [Project238]。[Name1] AS [Name1]、 [Project238]。[C2] AS [C2]、 [Project238]。[C3] AS [C3]、 [Project238]。[C1] AS [C4] FROM(選択 [GroupBy1]。[A1] AS [C1]、 [GroupBy1]。[K1] AS [名前]、 [GroupBy1]。[K2] AS [Name1]、 [GroupBy1]。[K3] AS [C2]、 [GroupBy1]。[K4] AS [C3]、 1 AS [C4] FROM(選択 [Project237]。[Name] AS [K1]、 [Project237]。[Name1] AS [K2]、 [Project237]。[C1] AS [K3]、 [Project237]。[C2] AS [K4]、 COUNT(1)AS [A1] FROM(選択 [Extent2]。[Name] AS [Name]、 [Extent3]。[Name] AS [Name1]、 DATEPART(年、[Join3]。[C11])AS [C1]、 DATEPART(月、[Join3]。[C12])AS [C2] FROM [OccupationHistory] AS [Extent1] INNER JOIN [Division] AS [Extent2] ON [Extent1]。[DivisionID] = [Extent2]。[Id] INNER JOIN [Position] AS [Extent3] ON [Extent1]。[PositionID] = [Extent3]。[Id] CROSS JOIN(SELECT [UnionAll59]。[C1] AS [C11]、[UnionAll118]。[C1] AS [C12] FROM(選択 [UnionAll58]。[C1] AS [C1] FROM(選択 [UnionAll57]。[C1] AS [C1] FROM(選択 [UnionAll56]。[C1] AS [C1] FROM(選択 [UnionAll55]。[C1] AS [C1] FROM(選択 [UnionAll54]。[C1] AS [C1] FROM(選択 [UnionAll53]。[C1] AS [C1] FROM(選択 [UnionAll52]。[C1] AS [C1] FROM(選択 [UnionAll51]。[C1] AS [C1] FROM(選択 [UnionAll50]。[C1] AS [C1] FROM(選択 [UnionAll49]。[C1] AS [C1] FROM(選択 [UnionAll48]。[C1] AS [C1] FROM(選択 [UnionAll47]。[C1] AS [C1] FROM(選択 [UnionAll46]。[C1] AS [C1] FROM(選択 [UnionAll45]。[C1] AS [C1] FROM(選択 [UnionAll44]。[C1] AS [C1] FROM(選択 [UnionAll43]。[C1] AS [C1] FROM(選択 [UnionAll42]。[C1] AS [C1] FROM(選択 [UnionAll41]。[C1] AS [C1] FROM(選択 [UnionAll40]。[C1] AS [C1] FROM(選択 [UnionAll39]。[C1] AS [C1] FROM(選択 [UnionAll38]。[C1] AS [C1] FROM(選択 [UnionAll37]。[C1] AS [C1] FROM(選択 [UnionAll36]。[C1] AS [C1] FROM(選択 [UnionAll35]。[C1] AS [C1] FROM(選択 [UnionAll34]。[C1] AS [C1] FROM(選択 [UnionAll33]。[C1] AS [C1] FROM(選択 [UnionAll32]。[C1] AS [C1] FROM(選択 [UnionAll31]。[C1] AS [C1] FROM(選択 [UnionAll30]。[C1] AS [C1] FROM(選択 [UnionAll29]。[C1] AS [C1] FROM(選択 [UnionAll28]。[C1] AS [C1] FROM(選択 [UnionAll27]。[C1] AS [C1] FROM(選択 [UnionAll26]。[C1] AS [C1] FROM(選択 [UnionAll25]。[C1] AS [C1] FROM(選択 [UnionAll24]。[C1] AS [C1] FROM(選択 [UnionAll23]。[C1] AS [C1] FROM(選択 [UnionAll22]。[C1] AS [C1] FROM(選択 [UnionAll21]。[C1] AS [C1] FROM(選択 [UnionAll20]。[C1] AS [C1] FROM(選択 [UnionAll19]。[C1] AS [C1] FROM(選択 [UnionAll18]。[C1] AS [C1] FROM(選択 [UnionAll17]。[C1] AS [C1] FROM(選択 [UnionAll16]。[C1] AS [C1] FROM(選択 [UnionAll15]。[C1] AS [C1] FROM(選択 [UnionAll14]。[C1] AS [C1] FROM(選択 [UnionAll13]。[C1] AS [C1] FROM(選択 [UnionAll12]。[C1] AS [C1] FROM(選択 [UnionAll11]。[C1] AS [C1] FROM(選択 [UnionAll10]。[C1] AS [C1] FROM(選択 [UnionAll9]。[C1] AS [C1] FROM(選択 [UnionAll8]。[C1] AS [C1] FROM(選択 [UnionAll7]。[C1] AS [C1] FROM(選択 [UnionAll6]。[C1] AS [C1] FROM(選択 [UnionAll5]。[C1] AS [C1] FROM(選択 [UnionAll4]。[C1] AS [C1] FROM(選択 [UnionAll3]。[C1] AS [C1] FROM(選択 [UnionAll2]。[C1] AS [C1] FROM(選択 [UnionAll1]。[C1] AS [C1] FROM(選択 変換(datetime、 '2001-01-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable1] UNION ALL 選択 変換(datetime、 '2001-02-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable2])AS [UnionAll1] UNION ALL 選択 変換(datetime、 '2001-03-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable3])AS [UnionAll2] UNION ALL 選択 変換(datetime、 '2001-04-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable4])AS [UnionAll3] UNION ALL 選択 変換(datetime、 '2001-05-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable5])AS [UnionAll4] UNION ALL 選択 変換(datetime、 '2001-06-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable6])AS [UnionAll5] UNION ALL 選択 変換(datetime、 '2001-07-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable7])AS [UnionAll6] UNION ALL 選択 変換(datetime、 '2001-08-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable8])AS [UnionAll7] UNION ALL 選択 convert(datetime、 '2001-09-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable9])AS [UnionAll8] UNION ALL 選択 変換(datetime、 '2001-10-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable10])AS [UnionAll9] UNION ALL 選択 変換(datetime、 '2001-11-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable11])AS [UnionAll10] UNION ALL 選択 変換(datetime、 '2001-12-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable12])AS [UnionAll11] UNION ALL 選択 変換(datetime、 '2002-01-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable13])AS [UnionAll12] UNION ALL 選択 変換(datetime、 '2002-02-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable14])AS [UnionAll13] UNION ALL 選択 変換(datetime、 '2002-03-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable15])AS [UnionAll14] UNION ALL 選択 convert(datetime、 '2002-04-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable16])AS [UnionAll15] UNION ALL 選択 変換(datetime、 '2002-05-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable17])AS [UnionAll16] UNION ALL 選択 変換(datetime、 '2002-06-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable18])AS [UnionAll17] UNION ALL 選択 変換(datetime、 '2002-07-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable19])AS [UnionAll18] UNION ALL 選択 変換(datetime、 '2002-08-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable20])AS [UnionAll19] UNION ALL 選択 変換(datetime、 '2002-09-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable21])AS [UnionAll20] UNION ALL 選択 変換(datetime、 '2002-10-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable22])AS [UnionAll21] UNION ALL 選択 変換(datetime、 '2002-11-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable23])AS [UnionAll22] UNION ALL 選択 変換(datetime、 '2002-12-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable24])AS [UnionAll23] UNION ALL 選択 convert(datetime、 '2003-01-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable25])AS [UnionAll24] UNION ALL 選択 convert(datetime、 '2003-02-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable26])AS [UnionAll25] UNION ALL 選択 変換(datetime、「2003-03-01 00:00:00.000」、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable27])AS [UnionAll26] UNION ALL 選択 変換(datetime、 '2003-04-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable28])AS [UnionAll27] UNION ALL 選択 convert(datetime、 '2003-05-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable29])AS [UnionAll28] UNION ALL 選択 convert(datetime、 '2003-06-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable30])AS [UnionAll29] UNION ALL 選択 convert(datetime、 '2003-07-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable31])AS [UnionAll30] UNION ALL 選択 convert(datetime、 '2003-08-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable32])AS [UnionAll31] UNION ALL 選択 変換(datetime、 '2003-09-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable33])AS [UnionAll32] UNION ALL 選択 convert(datetime、 '2003-10-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable34])AS [UnionAll33] UNION ALL 選択 変換(datetime、「2003-11-01 00:00:00.000」、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable35])AS [UnionAll34] UNION ALL 選択 変換(datetime、 '2003-12-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable36])AS [UnionAll35] UNION ALL 選択 convert(datetime、 '2004-01-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable37])AS [UnionAll36] UNION ALL 選択 convert(datetime、 '2004-02-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable38])AS [UnionAll37] UNION ALL 選択 変換(datetime、「2004-03-01 00:00:00.000」、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable39])AS [UnionAll38] UNION ALL 選択 変換(datetime、 '2004-04-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable40])AS [UnionAll39] UNION ALL 選択 convert(datetime、 '2004-05-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable41])AS [UnionAll40] UNION ALL 選択 変換(datetime、「2004-06-01 00:00:00.000」、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable42])AS [UnionAll41] UNION ALL 選択 convert(datetime、 '2004-07-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable43])AS [UnionAll42] UNION ALL 選択 変換(datetime、「2004-08-01 00:00:00.000」、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable44])AS [UnionAll43] UNION ALL 選択 変換(datetime、 '2004-09-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable45])AS [UnionAll44] UNION ALL 選択 convert(datetime、 '2004-10-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable46])AS [UnionAll45] UNION ALL 選択 変換(datetime、「2004-11-01 00:00:00.000」、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable47])AS [UnionAll46] UNION ALL 選択 変換(datetime、「2004-12-01 00:00:00.000」、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable48])AS [UnionAll47] UNION ALL 選択 convert(datetime、 '2005-01-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable49])AS [UnionAll48] UNION ALL 選択 変換(datetime、「2005-02-01 00:00:00.000」、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable50])AS [UnionAll49] UNION ALL 選択 convert(datetime、 '2005-03-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable51])AS [UnionAll50] UNION ALL 選択 convert(datetime、 '2005-04-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable52])AS [UnionAll51] UNION ALL 選択 convert(datetime、 '2005-05-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable53])AS [UnionAll52] UNION ALL 選択 変換(datetime、「2005-06-01 00:00:00.000」、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable54])AS [UnionAll53] UNION ALL 選択 convert(datetime、 '2005-07-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable55])AS [UnionAll54] UNION ALL 選択 変換(datetime、「2005-08-01 00:00:00.000」、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable56])AS [UnionAll55] UNION ALL 選択 convert(datetime、 '2005-09-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable57])AS [UnionAll56] UNION ALL 選択 変換(datetime、「2005-10-01 00:00:00.000」、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable58])AS [UnionAll57] UNION ALL 選択 convert(datetime、 '2005-11-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable59])AS [UnionAll58] UNION ALL 選択 convert(datetime、 '2005-12-01 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable60])AS [UnionAll59] 内部結合(選択 [UnionAll117]。[C1] AS [C1] FROM(選択 [UnionAll116]。[C1] AS [C1] FROM(選択 [UnionAll115]。[C1] AS [C1] FROM(選択 [UnionAll114]。[C1] AS [C1] FROM(選択 [UnionAll113]。[C1] AS [C1] FROM(選択 [UnionAll112]。[C1] AS [C1] FROM(選択 [UnionAll111]。[C1] AS [C1] FROM(選択 [UnionAll110]。[C1] AS [C1] FROM(選択 [UnionAll109]。[C1] AS [C1] FROM(選択 [UnionAll108]。[C1] AS [C1] FROM(選択 [UnionAll107]。[C1] AS [C1] FROM(選択 [UnionAll106]。[C1] AS [C1] FROM(選択 [UnionAll105]。[C1] AS [C1] FROM(選択 [UnionAll104]。[C1] AS [C1] FROM(選択 [UnionAll103]。[C1] AS [C1] FROM(選択 [UnionAll102]。[C1] AS [C1] FROM(選択 [UnionAll101]。[C1] AS [C1] FROM(選択 [UnionAll100]。[C1] AS [C1] FROM(選択 [UnionAll99]。[C1] AS [C1] FROM(選択 [UnionAll98]。[C1] AS [C1] FROM(選択 [UnionAll97]。[C1] AS [C1] FROM(選択 [UnionAll96]。[C1] AS [C1] FROM(選択 [UnionAll95]。[C1] AS [C1] FROM(選択 [UnionAll94]。[C1] AS [C1] FROM(選択 [UnionAll93]。[C1] AS [C1] FROM(選択 [UnionAll92]。[C1] AS [C1] FROM(選択 [UnionAll91]。[C1] AS [C1] FROM(選択 [UnionAll90]。[C1] AS [C1] FROM(選択 [UnionAll89]。[C1] AS [C1] FROM(選択 [UnionAll88]。[C1] AS [C1] FROM(選択 [UnionAll87]。[C1] AS [C1] FROM(選択 [UnionAll86]。[C1] AS [C1] FROM(選択 [UnionAll85]。[C1] AS [C1] FROM(選択 [UnionAll84]。[C1] AS [C1] FROM(選択 [UnionAll83]。[C1] AS [C1] FROM(選択 [UnionAll82]。[C1] AS [C1] FROM(選択 [UnionAll81]。[C1] AS [C1] FROM(選択 [UnionAll80]。[C1] AS [C1] FROM(選択 [UnionAll79]。[C1] AS [C1] FROM(選択 [UnionAll78]。[C1] AS [C1] FROM(選択 [UnionAll77]。[C1] AS [C1] FROM(選択 [UnionAll76]。[C1] AS [C1] FROM(選択 [UnionAll75]。[C1] AS [C1] FROM(選択 [UnionAll74]。[C1] AS [C1] FROM(選択 [UnionAll73]。[C1] AS [C1] FROM(選択 [UnionAll72]。[C1] AS [C1] FROM(選択 [UnionAll71]。[C1] AS [C1] FROM(選択 [UnionAll70]。[C1] AS [C1] FROM(選択 [UnionAll69]。[C1] AS [C1] FROM(選択 [UnionAll68]。[C1] AS [C1] FROM(選択 [UnionAll67]。[C1] AS [C1] FROM(選択 [UnionAll66]。[C1] AS [C1] FROM(選択 [UnionAll65]。[C1] AS [C1] FROM(選択 [UnionAll64]。[C1] AS [C1] FROM(選択 [UnionAll63]。[C1] AS [C1] FROM(選択 [UnionAll62]。[C1] AS [C1] FROM(選択 [UnionAll61]。[C1] AS [C1] FROM(選択 [UnionAll60]。[C1] AS [C1] FROM(選択 変換(datetime、 '2001-01-31 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable61] UNION ALL 選択 変換(datetime、 '2001-02-28 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable62])AS [UnionAll60] UNION ALL 選択 変換(datetime、 '2001-03-31 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable63])AS [UnionAll61] UNION ALL 選択 変換(datetime、 '2001-04-30 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable64])AS [UnionAll62] UNION ALL 選択 変換(datetime、 '2001-05-31 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable65])AS [UnionAll63] UNION ALL 選択 変換(datetime、 '2001-06-30 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable66])AS [UnionAll64] UNION ALL 選択 変換(datetime、 '2001-07-31 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable67])AS [UnionAll65] UNION ALL 選択 変換(datetime、 '2001-08-31 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable68])AS [UnionAll66] UNION ALL 選択 変換(datetime、 '2001-09-30 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable69])AS [UnionAll67] UNION ALL 選択 変換(datetime、 '2001-10-31 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable70])AS [UnionAll68] UNION ALL 選択 変換(datetime、 '2001-11-30 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable71])AS [UnionAll69] UNION ALL 選択 変換(datetime、 '2001-12-31 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable72])AS [UnionAll70] UNION ALL 選択 変換(datetime、 '2002-01-31 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable73])AS [UnionAll71] UNION ALL 選択 変換(datetime、 '2002-02-28 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable74])AS [UnionAll72] UNION ALL 選択 変換(datetime、 '2002-03-31 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable75])AS [UnionAll73] UNION ALL 選択 変換(datetime、 '2002-04-30 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable76])AS [UnionAll74] UNION ALL 選択 変換(datetime、 '2002-05-31 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable77])AS [UnionAll75] UNION ALL 選択 変換(datetime、 '2002-06-30 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable78])AS [UnionAll76] UNION ALL 選択 変換(datetime、 '2002-07-31 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable79])AS [UnionAll77] UNION ALL 選択 変換(datetime、 '2002-08-31 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable80])AS [UnionAll78] UNION ALL 選択 変換(datetime、 '2002-09-30 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable81])AS [UnionAll79] UNION ALL 選択 変換(datetime、 '2002-10-31 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable82])AS [UnionAll80] UNION ALL 選択 変換(datetime、 '2002-11-30 00:00:00.000'、121)AS [C1] FROM(SELECT 1 AS X)AS [SingleRowTable83])AS [UnionAll81] UNION ALL 選択 変換(datetime、 '2002-12-31 00:00:00.000'、121)AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable84]) AS [UnionAll82] UNION ALL SELECT convert(datetime, '2003-01-31 00:00:00.000', 121) AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable85]) AS [UnionAll83] UNION ALL SELECT convert(datetime, '2003-02-28 00:00:00.000', 121) AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable86]) AS [UnionAll84] UNION ALL SELECT convert(datetime, '2003-03-31 00:00:00.000', 121) AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable87]) AS [UnionAll85] UNION ALL SELECT convert(datetime, '2003-04-30 00:00:00.000', 121) AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable88]) AS [UnionAll86] UNION ALL SELECT convert(datetime, '2003-05-31 00:00:00.000', 121) AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable89]) AS [UnionAll87] UNION ALL SELECT convert(datetime, '2003-06-30 00:00:00.000', 121) AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable90]) AS [UnionAll88] UNION ALL SELECT convert(datetime, '2003-07-31 00:00:00.000', 121) AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable91]) AS [UnionAll89] UNION ALL SELECT convert(datetime, '2003-08-31 00:00:00.000', 121) AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable92]) AS [UnionAll90] UNION ALL SELECT convert(datetime, '2003-09-30 00:00:00.000', 121) AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable93]) AS [UnionAll91] UNION ALL SELECT convert(datetime, '2003-10-31 00:00:00.000', 121) AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable94]) AS [UnionAll92] UNION ALL SELECT convert(datetime, '2003-11-30 00:00:00.000', 121) AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable95]) AS [UnionAll93] UNION ALL SELECT convert(datetime, '2003-12-31 00:00:00.000', 121) AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable96]) AS [UnionAll94] UNION ALL SELECT convert(datetime, '2004-01-31 00:00:00.000', 121) AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable97]) AS [UnionAll95] UNION ALL SELECT convert(datetime, '2004-02-29 00:00:00.000', 121) AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable98]) AS [UnionAll96] UNION ALL SELECT convert(datetime, '2004-03-31 00:00:00.000', 121) AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable99]) AS [UnionAll97] UNION ALL SELECT convert(datetime, '2004-04-30 00:00:00.000', 121) AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable100]) AS [UnionAll98] UNION ALL SELECT convert(datetime, '2004-05-31 00:00:00.000', 121) AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable101]) AS [UnionAll99] UNION ALL SELECT convert(datetime, '2004-06-30 00:00:00.000', 121) AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable102]) AS [UnionAll100] UNION ALL SELECT convert(datetime, '2004-07-31 00:00:00.000', 121) AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable103]) AS [UnionAll101] UNION ALL SELECT convert(datetime, '2004-08-31 00:00:00.000', 121) AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable104]) AS [UnionAll102] UNION ALL SELECT convert(datetime, '2004-09-30 00:00:00.000', 121) AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable105]) AS [UnionAll103] UNION ALL SELECT convert(datetime, '2004-10-31 00:00:00.000', 121) AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable106]) AS [UnionAll104] UNION ALL SELECT convert(datetime, '2004-11-30 00:00:00.000', 121) AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable107]) AS [UnionAll105] UNION ALL SELECT convert(datetime, '2004-12-31 00:00:00.000', 121) AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable108]) AS [UnionAll106] UNION ALL SELECT convert(datetime, '2005-01-31 00:00:00.000', 121) AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable109]) AS [UnionAll107] UNION ALL SELECT convert(datetime, '2005-02-28 00:00:00.000', 121) AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable110]) AS [UnionAll108] UNION ALL SELECT convert(datetime, '2005-03-31 00:00:00.000', 121) AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable111]) AS [UnionAll109] UNION ALL SELECT convert(datetime, '2005-04-30 00:00:00.000', 121) AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable112]) AS [UnionAll110] UNION ALL SELECT convert(datetime, '2005-05-31 00:00:00.000', 121) AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable113]) AS [UnionAll111] UNION ALL SELECT convert(datetime, '2005-06-30 00:00:00.000', 121) AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable114]) AS [UnionAll112] UNION ALL SELECT convert(datetime, '2005-07-31 00:00:00.000', 121) AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable115]) AS [UnionAll113] UNION ALL SELECT convert(datetime, '2005-08-31 00:00:00.000', 121) AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable116]) AS [UnionAll114] UNION ALL SELECT convert(datetime, '2005-09-30 00:00:00.000', 121) AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable117]) AS [UnionAll115] UNION ALL SELECT convert(datetime, '2005-10-31 00:00:00.000', 121) AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable118]) AS [UnionAll116] UNION ALL SELECT convert(datetime, '2005-11-30 00:00:00.000', 121) AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable119]) AS [UnionAll117] UNION ALL SELECT convert(datetime, '2005-12-31 00:00:00.000', 121) AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable120]) AS [UnionAll118] ON (((DATEPART (year, [UnionAll59].[C1])) = (DATEPART (year, [UnionAll118].[C1]))) OR ((DATEPART (year, [UnionAll59].[C1]) IS NULL) AND (DATEPART (year, [UnionAll118].[C1]) IS NULL))) AND (((DATEPART (month, [UnionAll59].[C1])) = (DATEPART (month, [UnionAll118].[C1]))) OR ((DATEPART (month, [UnionAll59].[C1]) IS NULL) AND (DATEPART (month, [UnionAll118].[C1]) IS NULL))) ) AS [Join3] WHERE ([Extent1].[StartDate] <= [Join3].[C12]) AND ((CASE WHEN ([Extent1].[EndDate] IS NOT NULL) THEN [Extent1].[EndDate] ELSE GetDate() END) >= [Join3].[C11]) ) AS [Project237] GROUP BY [Project237].[Name], [Project237].[Name1], [Project237].[C1], [Project237].[C2] ) AS [GroupBy1] ) AS [Project238] ORDER BY [Project238].[C2] ASC, [Project238].[C3] ASC, [Project238].[Name] ASC, [Project238].[Name1] ASC; Method Name:GetEmployeesCount; Class Name:CompanyEmployees.Data.ReportBuilder; Elapsed Miliseconds:336
あとがき
まだ多くのバグがあると確信していますが、できるだけ早くすべてのエラーを修正しようとします。また、尊敬されるコミュニティハブからこのプロファイラーをどうするかアドバイスを求めたいので、一方で無料の製品を作りたいが、同時にいくらかのお金を稼ぎたい。現在、私はプロファイラーを個人的な使用のために完全に無料にし、企業に支払いをすることを考えていますが、再び最低価格で20-30ドルです。まあ、または単に寄付ボタンでそれを自由のままにしておきます。
ご清聴ありがとうございました。このツールが役に立つことを願っています。
PS:すべての質問、バグレポートなどについては、developer @ ef-logger.comまたはst.glushak@gmail.comにメールをお送りください。
Nuget EF6: https://www.nuget.org/packages/EFlogger-For6/
Nuget EF4 — 5: https://www.nuget.org/packages/EFlogger-For4/
Updated: :