Generated code - Troubleshooting and debugging

Preface

Sometimes you want deep insight in what's really going on inside the runtime libraries, what SQL was generated and in what order did the queries get executed, and not only during development, but also after deployment, when an application in production doesn't do what it should do. LLBLGen Pro provides a fine-grained, robust tracing facility build on top of the .NET tracing functionality. See for more information about .NET tracing, the .NET documentation on the Trace class which contains links to setup tracing in your application: (opens online MSDN help) Tracing and Instrumenting Applications in Visual Basic and Visual C# .NET tracing offers easy to setup tracing which can be switched on and off by settings in the .config file of your application (app.config or web.config)


note Note:
Tracing doesn't affect performance when all switches are switched off (the default) or not defined in the .config file. Though when a switch is turned on, the tracing code will affect performance. Use the right switches for your tracing needs and leave them off in production code or don't specify them at all, unless troubleshooting has to take place.

note Note:
The traceswitch for the DQEs is a static (shared) switch as code shared among all DQE's is using the switch as well. This means that if you're using simultaneously the DQEs of multiple databases, and you switch on tracing for one of the DQE's and actively switch tracing off for the other DQEs, tracing won't work as the switch will be turned off. Traceswitches have to be static/shared as the .NET tracing framework requires that. To avoid switching off the traceswitch of the DQE you want tracing to be enabled, enable tracing of all DQEs used in your application.

Conventions

LLBLGen Pro's generated code offers two categories of tracing: info level and verbose level, and a variety of trace switches to switch tracing on or off. When a trace switch is switched on, the runtime libraries will produce trace output, depending on which switch you've turned on and to which level: verbose or info. This way you can keep the trace output small and still keep an eye on what's going on behind the scenes.

A trace listener can be defined in the .config file. If no trace listener is defined, and the application is started in debug mode from within VS.NET (using F5), the tracing output will be delivered to the output window of VS.NET. This way, you can use the tracing functionality during development without leaving the editor. .NET comes with some basic trace listeners, for example for writing the trace information to a file or to the event log. You can also write trace listeners yourself. For more information see the online MSDN help link mentioned above.

Every method which has tracing functionality added, has a "Method Enter" and a "Method Exit" message. Most of the time these are logged at the info level, though for methods which are called a lot, they're defined for the verbose level, so to see them, you have to switch on the particular trace switch at level '4' (verbose). You can use these two messages for formatting/searching the trace output. When a method has multiple overloads, the number of arguments is specified with a number, for example CreateDeleteDQ(3).

At the verbose level, LLBLGen Pro will report additional information, if applicable. For example the entity field information, parameter values and other data which is only required when all information has to be retrieved. At the verbose level, all info level tracing is also provided.

All trace switches have to be defined in the .config file, in a system.Diagnostics tag, which has to be placed inside the configuration tag. You don't have to define all switches, you can omit any switch definition if you'd like. When a switch isn't defined, it's considered turned off and no trace information is produced which is tied to that switch. The following snippet shows all available trace switches. These switches are described in detail in the following sections. The snippet below defines some switches with the value '3' (info level, switched on), '4' (verbose level, switched on) or '0' (switched off).

<system.diagnostics>
	<switches>
		<add name="SqlServerDQE" value="3" />
		<add name="AccessDQE" value="4" />
		<add name="OracleDQE" value="4" />
		<add name="FirebirdDQE" value="4" />
		<add name="MySqlDQE" value="4" />
		<add name="DB2DQE" value="4" />
		<add name="PostgreSqlDQE" value="4" />
		<add name="SybaseAsaDQE" value="4" />
		<add name="SybaseAseDQE" value="4" />
		<add name="ORMGeneral" value="0" />
		<add name="ORMQueryExecution" value="0" />
		<add name="ORMStateManagement" value="0" />
		<add name="ORMPersistenceExecution" value="3" />
		<add name="LinqExpressionHandler" value="3" />
	</switches>
</system.diagnostics>

Dynamic Query Engine tracing

To enable Dynamic Query Engine (DQE) tracing, you can for each different DQE switch it on to level 3 (info) or level 4 (verbose). To do that, you have to make sure the switch for the DQE of the database you want trace information for is defined in the .config file, as shown in the previous section. The following table shows the switches per database type.

DQE / database Trace switch
SqlServer SqlServerDQE
MS Access AccessDQE
Oracle (ODP.NET/Microsoft Oracle Provider) OracleDQE
Firebird FirebirdDQE
MySQL MySqlDQE
IBM DB2 DB2DQE
PostgreSql PostgreSqlDQE
Sybase ASA SybaseAsaDQE
Sybase ASE SybaseAseDQE


For all DQE's the levels 3 (info) and 4 (verbose) are supported and offer the same trace information. For each level, the trace information they'll provide is listed below.
Info level tracing
When for a DQE, the trace switch is switched on to level 3 (info level), the following information is provided:

Verbose level tracing
When for a DQE the trace switch is switched on to level 4 (verbose level), the following information is provided, besides the information provided at the info level:

ORM Support classes tracing

The ORM Support classes offer three different switches to trace different functionality. These switches are described below:

These three switches offer also the two levels supported: 3 for info level and 4 for verbose level. Below, per level per switch is described which information is produced. Not every method in the ORM Support classes has tracing functionality. If you need tracing support for a method which doesn't has tracing support at the moment, please send an email to support@llblgen.com with your request.
Info level tracing
For the switch ORMGeneral, the following information is provided when it is switched on to level 3:

For the switch ORMStateManagement, the following information is provided when it is switched on to level 3:

For the switch ORMQueryExecution, the following information is provided when it is switched on to level 3:

For the switch ORMPersistenceExecution, the following information is provided when it is switched on to level 3:

Verbose level tracing
For the switch ORMGeneral, the following information is provided when it is switched on to level 4, besides the information provided for level 3:

For the switch ORMStateManagement, the following information is provided when it is switched on to level 4, besides the information provided for level 3:

For the switch ORMQueryExecution, the following information is provided when it is switched on to level 4, besides the information provided for level 3:

For the switch ORMPersistenceExecution, the following information is provided when it is switched on to level 4, besides the information provided for level 3:

Linq to LLBLGen Pro tracing

The Linq to LLBLGen Pro provider also supports tracing. It has two levels: Info level tracing (3), which is recommended if this tracer is used, and Verbose level tracing (4). Info level tracing emits the expression tree into the output in textual form. This is useful to get more information about what was exactly passed to the Linq provider. Verbose level tracing is really verbose: it emits a complete visit trace of all methods called during the handling of the linq query. In general this isn't recommended as it eats a lot of performance and also emits a lot of output. Only use level 4 for this tracer if you absolutely have to.

Debugger Visualizers

Visual Studio offers the ability to enable visualizer objects for given types during debugging sessions called Debugger visualizers. If you've already done some debugging inside VS.NET you've seen some of them already: the string debugger visualizer for example is one of the debugger visualizers shipped with VS.NET which can be activated when the execution is paused and you hover over a type with the mouse and click the magnifyer glass icon.

For several types in the LLBLGen Pro generated code and runtime library, Debugger Visualizers are developed so debugging code using LLBLGen Pro generated code is easier.
Installation
Copy the SD.LLBLGen.Pro.DebugVisualizersXXYY.dll from the folder Frameworks\LLBLGen Pro\RuntimeLibraries\DebuggerVisualizers\xxyy\ to the folder:
My Documents\Visual Studio xxyy\Visualizers\ Also copy the ORMSupportClasses dll and the DQE dll of your choice to that folder. 'xxyy' is the vs.net year number of the vs.net version you're using. LLBLGen Pro ships debug visualizers for 2008, 2010 and 2012.

You need to restart VS.NET to make them available to you. In a debug session, when you hit a breakpoint, you can hover your mouse over a variable of a type of any of the supported types below and you'll see a magnifyer glass which allows you to open the debug visualizer for that type with the data in that instance.
Debug visualizers included
The following debug visualizers are included:

Predicate/PredicateExpression
The predicate / Predicate expression visualizer visualizes the predicate as a WHERE clause. It will use a pseudo DQE and pseudo DB specific creator to create a string which is displayed in a viewer. Also displayed are the parameters of the complete filter and the values of these parameters.

EntityCollection (Selfservicing/adapter)
Simple form with a DataGrid set to readonly/AllowNavigation set to false (to avoid lazy loading) for SelfServicing entity collections and with AllowNavigation set to true for Adapter, which displays the collection using normal databinding. The form also shows a textbox with the type the collection is set for, which is typically the type the factory produces.

RelationCollection / Relationpredicatebucket
Similar to PredicateExpression, though it will show the actual SQL generated. The RelationPredicateBucket visualizer has a tab control with both a visualizer for the PredicateExpression as for the RelationCollection.

SortExpression
Simple visualizer which shows the sort expression in a textbox, similar to the predicate expression visualizer

GroupByCollection
Simple viewer which views the grouped fields, one on each line and the HAVING clause as a normal predicate expression.

PrefetchPath
The visualizer for prefetch paths displays the path as nodes in a tree. To handle polymorphic paths, the path element is represented by a node, and all nodes added to that path element are added as nodes. The visualizer uses reflection to get a hold on the EntityType type definition to produce proper names for the node destinations/types to fetch.

Expression
The visualizer for the expression is similar to the PredicateVisualizer: it shows the expression without beautification and the parameters.

LLBLGen Pro Runtime Framework v4.0 documentation. ©2013 Solutions Design bv