public override object GetData(ITabContext context) { var commands = context.GetMessages<CommandTimelineMessage>().ToArray(); if (!commands.Any()) { return null; } var ordinal = 1; var duplicationKeys = new HashSet<string>(); var duplicationCount = 0; var queries = new TabSection("Ordinal", "Database", "Command", "Parameters", "CommandType", "With Transaction", "Records", "IsError", "Duration", "Offset"); foreach (var command in commands) { var parameters = new TabSection("Name", "Value", "DbType", "Direction"); foreach (var parameter in command.Parameters) { parameters.AddRow() .Column(parameter.ParameterName) .Column(parameter.Value) .Column(parameter.DbType.ToString()) .Column(parameter.Direction.ToString()); } var row = queries.AddRow() .Column(ordinal) .Column(command.Database) .Column(command.CommandText) .Column(command.Parameters.Any() ? parameters : null) .Column(command.CommandType.ToString()) .Column(command.WithTransaction) .Column(command.Records ?? 0) .Column(command.IsError) .Column(command.Duration) .Column(command.Offset); var isDuplicated = !duplicationKeys.Add(command.CommandText); if (isDuplicated) { row.WarnIf(true); duplicationCount++; } ordinal++; } var sqlStatistics = new TabSection("Queries", "Duplication", "Total Query Duration"); sqlStatistics.AddRow() .Column(commands.Length) .Column(duplicationCount) .Column(commands.Select(x => x.Duration).Aggregate((x, y) => x.Add(y))); var root = new TabObject(); root.AddRow().Key("SQL Statistics").Value(sqlStatistics); root.AddRow().Key("Queries").Value(queries); return root.Build(); }
public override object GetData(ITabContext context) { var connectionLifetimes = context.GetMessages<ConnectionLifetimeTimelineMessage>().ToArray(); var transactionLifetimes = context.GetMessages<TransactionLifetimeTimelineMessage>().ToArray(); var transactionEvents = context.GetMessages<TransactionEventTimelineMessage>().ToArray(); var commands = context.GetMessages<CommandTimelineMessage>().ToArray(); var statisticsSection = new TabSection("Database", "Queries", "Total Transaction Duration"); var eventSection = new TabSection("Database", "Events", "Queries", "IsCommited", "Total Duration"); // Statistics foreach (var transactionLifetime in transactionLifetimes.OrderBy(x => x.Offset).ToArray()) { statisticsSection.AddRow() .Column(connectionLifetimes.First(x => x.ConnectionId == transactionLifetime.ConnectionId).Database) .Column(commands.Count(x => x.TransactionId.HasValue && x.TransactionId.Value == transactionLifetime.TransactionId)) .Column(transactionLifetime.Duration); } // Events foreach (var transactionLifetime in transactionLifetimes.OrderBy(x => x.Offset).ToArray()) { var queries = commands .Where(x => x.TransactionId.HasValue && x.TransactionId.Value == transactionLifetime.TransactionId) .ToArray(); var events = transactionEvents .Where(x => x.TransactionId == transactionLifetime.TransactionId) .Select(x => new { EventType = "Transaction", EventName = x.TransactionEvent.ToString(), Duration = x.Duration, Offset = x.Offset }) .Concat(queries .Select(x => new { EventType = "Command", EventName = x.CommandText, Duration = x.Duration, Offset = x.Offset }) ) .OrderBy(x => x.Offset) .ToArray(); var eventDetailSection = new TabSection("EventType", "EventName", "Duration", "Offset"); var duplicatedKeys = new HashSet<string>(); foreach (var @event in events) { var row = eventDetailSection.AddRow() .Column(@event.EventType) .Column(@event.EventName) .Column(@event.Duration) .Column(@event.Offset); if (@event.EventType == "Command") { row.WarnIf(!duplicatedKeys.Add(@event.EventName)); } } eventSection.AddRow() .Column(transactionLifetime.Database) .Column(eventDetailSection) .Column(commands.Length) .Column(transactionLifetime.IsCommited) .Column(transactionLifetime.Duration); } var root = new TabObject(); root.AddRow().Key("Transaction Statistics").Value(statisticsSection); root.AddRow().Key("Transaction Events").Value(eventSection); return root.Build(); }