Application configuration through .config files

Info

This section is for .NET Framework only, as the .NET Standard build of the runtime framework doesn't support .config files. To configure your application on .Netstandard, please use the RuntimeConfiguration system.

The generated code, both adapter and selfservicing, offer several application-wide configuration settings which can be added to the .config file of your application (be it the app.config file for a .exe application or the web.config file for a service/web-application).

Besides the settings for the connection string (see Compiling the code) and trace listener setup (see Troubleshooting and debugging), you can configure several core elements of how the generated code will behave.

Several of these elements have been described elsewhere in the manual as well. They're listed here for clarity so you have a single section to find all config file settings for an LLBLGen Pro application. When mentioned here, we've added a link to their actual documentation so you will see their documentation in context.

Dependency Injection settings

Dependency injection auto-discovery is switched off by default. To enable it, add a setting to the .config file. See: Setting up and using Dependency Injection - Auto-discovery of instance types

To manually specify which assemblies the LLBLGen Pro runtime framework should discover for injectable types, you've to add a section to the .config file. See: Setting up and using Dependency Injection - Manual discovery through dependencyInjectionInformation sections in the .config file

Trace switch settings

To setup tracing in LLBLGen Pro, you've to add a section of switch elements to the .config file. See Troubleshooting and debugging - Conventions.

Culture specific format specifications

To specify the culture to use for serializing and deserializing System.Single, System.Double and System.Decimal typed values to and from XML, you should add the following element to the appSettings element of the config file of the applications which serialize and deserialize XML data, where name of culture is replaced with either nothing (so value is empty, for the invariant culture) or the name of the culture to use, e.g. nl-NL or en-US. For the full list of iso culture names please see the CultureInfo class documentation in the MSDN.

<add key="cultureNameForXmlValueConversion" value="name of culture" />

Entity behavior settings

Setting 'Fetched' state

To automatically mark a saved entity as 'Fetched', add a setting to the .config file. See Using the entity classes - Setting the EntityState to Fetched automatically after a save: for adapter and for selfservicing.

Bypass built-in validation

To bypass build-in validation logic in favor for your own validation logic, add a line to the config file settings. See: Validation per field or per entity - Bypassing build-in validation logic

Define Scale overflow correction action

To define the correction action for a Scale overflow error, add a line to the config file settings. See: Validation per field or per entity - Defining the Scale overflow correction action to use

Specify string hashcode behavior

To specify that the LLBLGen Pro runtime should use case insensitive hashcodes for strings (the hashcode for "Foo" is the same as for "FoO"), the following key should be added to the appSettings element of the config file of the application:

<add key="caseSensitiveStringHashCodes" value="false" />

By default, hashcodes are case sensitive, omitting this setting or setting it to true in the config file results in the default behavior. Hashcodes for string values in entity fields are used in prefetch path mergers and for example projection distinct filtering.

In general you should keep this setting set to the default (true). Only set this to false if you're working with a case-insensitive database which has FK values which differ only in casing from their PK counterparts (e.g. the FK field value is "Foo" and the PK field value is "foo".

Specify non-nullable field set to null behavior

By default, setting a nonnullable field to null / nothing is silently resulting in a no-op, without any exception. However it can be beneficial to have this as a mandatory validation option. To make the runtime throw an ArgumentOutOfRangeException, the following key should be added to the appSettings element of the config file of the application:

<add key="makeSettingNonNullableFieldsToNullFatal" value="true" />

The default is false.

Multi-tenancy support

Multi-tenancy support is implemented through catalog/schema name overwriting at runtime. This is configurable through code and by definitions in the .config file of your application.

Important!

Catalog and schema name overwriting uses case sensitive string comparisons. So if you define a source catalog name of NORTHWIND and the name of the catalog in the metadata (and thus query) is actually Northwind, no name is overwritten.

Catalog name overwriting (SQL Server, MySQL)

For generated code targeting SqlServer or MySQL, it can sometimes be necessary to use the generated code with a catalog with a different name than the catalog the project was created with. As LLBLGen Pro generates the catalog name into the code, it might be necessary to specify a way to rename the catalog name in the generated code at runtime with a given name.

LLBLGen Pro supports multiple catalogs per project, so you can specify more than one rename definition. This feature is similar to the feature discussed in Using the generated code / Adapter / DataAccessAdapter functionality (multi name setting) as it also offers a way to rename multiple catalogs in one go.

The renamed data is stored in static hashtables which assure that the Dynamic Query Engines (DQE) for SqlServer and MySQL use the right catalog names without losing any performance.

To setup the renaming of catalogs, follow these steps. The first tag in the configuration tag in the .config file has to be the configSections tag. In there, place a section definition tag as shown in the example below:

<configSections>
    <section name="sqlServerCatalogNameOverwrites" type="System.Configuration.NameValueSectionHandler" />
</configSections>
<configSections>
    <section name="mySqlCatalogNameOverwrites" type="System.Configuration.NameValueSectionHandler" />
</configSections>

Then, the catalog name overwrite definitions have to be placed in key/value pairs inside the databaseCatalogNameOverwrites or tag, similar as the following examples. The databaseCatalogNameOverwrites tag has to be placed inside the configuration tag of the .config file as well.

<sqlServerCatalogNameOverwrites>
    <add key="OldNameCatalog1" value="NewNameCatalog1" />
    <add key="OldNameCatalog2" value="NewNameCatalog2" />
</sqlServerCatalogNameOverwrites>
<mySqlCatalogNameOverwrites>
    <add key="OldNameCatalog1" value="NewNameCatalog1" />
    <add key="OldNameCatalog2" value="NewNameCatalog2" />
</mySqlCatalogNameOverwrites>
Info

For ASP.NET applications, the section declaration has to contain in the type attribute the full type with version and culture, otherwise you'll get an exception at runtime. The specific type declaration is specific for the .NET version you're using and you can find examples how to specify it from the machine.config file in %WINDIR%\Microsoft .NET\Framework version\CONFIG.

This example makes sure that at runtime any reference in the persistence info of the elements in the generated code to the catalog 'OldCatalogName1' is renamed to 'NewCatalogName1' and any reference to 'OldCatalogName2' is renamed to 'NewCatalogName2'.

You can also specify an empty string as new name. In that case, the DQE will not specify a catalog name in the generated SQL elements, which will make the SQL target the catalog specified in the connection string.

Wildcards

To overwrite all catalog names in the generated code with a single name, you can use the wildcard * to specify the new name of the catalog to use. All catalog names in the generated code will in that case be replaced with the name specified as value with * as key. Specifying * as key overrides all other specified catalog name overwrites.

Schema name overwriting (SqlServer, Oracle, DB2, PostgreSql)

Besides the ability to rename catalog names, LLBLGen Pro offers also the functionality to rename schema names. This is supported for SqlServer, Oracle, PostgreSql and DB2 databases. These sections work similar to the previously discussed catalog rename feature for SqlServer.

Important!

Keep in mind that schema renames are global. So you can't rename schema 'dbo' in catalog 'Foo' to 'schema1' and 'dbo' in catalog 'Bar' to 'schema2'.

To setup the renaming of schemas, follow these steps. The first tag in the configuration tag in the .config file has to be the configSections tag. In there, place a section definition tag as shown in the example below.

If you also use catalog name renaming, you can place the section definition with the catalog rename section inside the same configSections tag. The following example shows all supported section definitions for schema name overwriting, one for SqlServer, one for DB2, one for Oracle and one for PostgreSql. This way, you can define schema overwriting for Oracle, DB2 PostgreSql and SqlServer in one .config file.

<configSections>
    <section name="sqlServerSchemaNameOverwrites" type="System.Configuration.NameValueSectionHandler" />
    <section name="oracleSchemaNameOverwrites" type="System.Configuration.NameValueSectionHandler" />
    <section name="db2SchemaNameOverwrites" type="System.Configuration.NameValueSectionHandler" />
    <section name="postgreSqlSchemaNameOverwrites" type="System.Configuration.NameValueSectionHandler" />
</configSections>

You then can define the schema name overwrites in their own section:

<sqlServerSchemaNameOverwrites>
    <add key="dbo" value="FooBar" />
</sqlServerSchemaNameOverwrites>
<db2SchemaNameOverwrites>
    <add key="OWNER" value="FooBar" />
</db2SchemaNameOverwrites>
<postgreSqlSchemaNameOverwrites>
    <add key="public" value="FooBar" />
</postgreSqlSchemaNameOverwrites>
<oracleSchemaNameOverwrites>
    <add key="SCOTT" value="HR" />
</oracleSchemaNameOverwrites>

You can also specify an empty string. In that case, the schema name isn't generated into the SQL. For some situations this can be handy, though keep in mind that if you use empty strings for schemas on SqlServer, you also have to specify an empty string for the catalog name in a catalog name overwrite section.

Wildcards

To overwrite all schema names in the generated code with a single name, you can use the wildcard * to specify the new name of the schema to use. All schema names in the generated code will in that case be replaced with the name specified as value with * as key. Specifying * as key overrides all other specified schema name overwrites.

Trigger based sequence values (Oracle/Firebird)

Some Oracle schemas or Firebird databases use triggers to set the sequence value when a record is inserted. LLBLGen Pro's generated code for Oracle or Firebird uses a second query to first determine the next value of the sequence (using NEXTVAL on Oracle, using 1 instead of 0 in GEN_ID on Firebird), then pass that value to the insert query as a normal value.

If that code is then used to insert a row in a table with a trigger for sequence values, the trigger will update the inserted value with a new value, making the value returned to the LLBLGen Pro runtime core not the value the trigger inserted into the sequenced field.

To overcome this, the Oracle and Firebird Dynamic Query Engines (DQE) can be configured to execute a sequence retrieval query which checks for the current value (using CURRVAL on Oracle, using 0 instead of 1 in GEN_ID on Firebird) after the insert took place, instead of the sequence retrieval query which checks for the next value before the insert takes place.

To do that, add the following tag to the configuration's appSettings section:

<add key="OracleTriggerSequences" value="true" />
<add key="FirebirdTriggerSequences" value="true" />

A value of false or omitting the tag will cause normal behavior, a sequence call which asks for the next value before the insert.

Forced Ansi-joins (Oracle only)

Info

All the SQL engines (DQE's) of LLBLGen Pro use ansi-joins by default.

To disable ansi joins, add the following tag to the configuration's appSettings section in the .config file of your application:

<add key="OracleAnsiJoins" value="false" />

A value of true or omitting the tag will cause normal behavior, ansi joins.

Catalog name inclusion (MySQL only)

By default, the catalog name isn't included in queries for MySQL, as versions of LLBLGen Pro before v3 didn't support multiple catalogs for MySQL and enabling it by default would break a lot of code. If you use multiple catalogs in your project for MySQL, you have to enable this setting. Add the following tag to the configuration's appSettings section in the .config file of your application:

<add key="mySqlIncludeCatalogNameInObjectNames" value="true" />

A value of false or omitting the tag will cause normal behavior: no catalog names in queries. To be able to overwrite catalog names in the queries, this setting has to be enabled.

Always use unmanaged provider (ODP.NET v12c)

By default, the first factory the ODP.NET DQE will look for will be Oracle.ManagedDataAccess.Client, which is the managed provider shipped in the 12c ODP.NET version. If this factory isn't found, the Oracle.DataAccess.Client factory is tried. If that one isn't found either, the DQE/driver will give up.

In some situations it might be necessary to choose the unmanaged provider, as XmlType isn't supported on the managed provider, and as the managed provider is chosen by default, this could lead to a catch-22, because ODP.NET installs both the unmanaged and the managed provider.

To make sure the unmanaged provider is chosen at runtime and the .NET version used is .NET 4 or higher,  add the following tag to the configuration's appSettings section in the .config file of your application:

<add key="ODPNETAlwaysChooseUnmanagedProvider" value="true" />

A value of false or omitting the tag will cause normal behavior: the managed provider is first tried, then the unmanaged provider, if the managed provider isn't found.

DQE Compatibility mode (SQL Server only)

To set the compatibility mode of the SqlServer DQE in the .config file of your application, add the following element to the appSettings section of your application's .config file:

<add key="SqlServerDQECompatibilityLevel" value="number" />

where number is either 0, 1, 2, 3, 4 , 5 or 6:

  • 0 for SqlServerCompatibilityLevel.SqlServer7
  • 1 for SqlServerCompatibilityLevel.SqlServer2000
  • 2 for SqlServerCompatibilityLevel.SqlServer2005 (also for 2008/2008 R2, which doesn't require a separate compatibility level)
  • 3 for SqlServerCompatibilityLevel.SqlServerCE3x (Sqlserver CE 3.0 and 3.1)
  • 4 for SqlServerCompatibilityLevel.SqlServerCE35
  • 5 for SqlServerCompatibilityLevel.SqlServerCE40
  • 6 for SqlServerCompatibilityLevel.SqlServer2012 (also for 2014/2016, which don't require a separate compatibility level)

The default is 2 or SqlServer2005+ so omitting this tag will result in the SqlServer 2005+ compatibility mode. Setting this compatibility level is setting the default value which is used in every SQL Server Dynamic Query Engine instance to produce a SQL query. When using Adapter, you can overrule this setting at runtime for a single DataAccessAdapter instance by setting the property CompatibilityLevel of the DataAccessAdapter instance.

See Database specific features, SQL Server Specific: compatibility mode,  for details about the SQL specific effects each compatibility mode has.

DQE Compatibility mode (Firebird only)

To set the compatibility mode of the Firebird DQE in the .config file of your application, add the following element to the appSettings section of your application's .config file:

<add key="FirebirdDQECompatibilityLevel" value="number" />

where number is either 0 or 1:

  • 0 for FirebirdCompatibilityLevel.Firebird15
  • 1 for FirebirdCompatibilityLevel.Firebird2x

The default is 1 or Firebird 2x. If you're using Firebird 1.5, please set it to 0. Setting it to 0, Firebird15, will cause the DQE to not emit aliases in subqueries inside SELECT statements as this feature was introduced in Firebird 2.0.

If you're using Firebird 2.0 or higher and you want to use Linq to LLBLGen Pro, please leave the compatibility mode for Firebird to 1 (so compatibility level Firebird2x), as Linq to LLBLGen Pro will produce derived tables for some queries which require aliases on fields.

DQE Compatibility mode (Oracle only)

To set the compatibility mode of the Oracle DQE in the .config file of your application, add the following element to the appSettings section of your application's .config file:

<add key="OracleDQECompatibilityLevel" value="number" />

where number is either 0 or 1:

  • 0 for OracleCompatibilityLevel.Oracle9i10g11g
  • 1 for OracleCompatibilityLevel.Oracle12c (Default)

The default is 1 or Oracle 12c+. Having this setting set to 1, Oracle12c, will make the DQE to emit 12c compatible paging queries using OFFSET FETCH ONLY, and will not emit sequence value retrieval queries for identity fields. 

Case-insensitive names in SQL queries on case sensitive DBs (DB2, Firebird, Oracle, Postgresql only)

For DB2, Firebird, Oracle and PostgreSQL there is a setting available which controls whether the names in the queries for catalogs/schemas/tables/views/stored procedures/table valued functions and fields are wrapped with "" (the default, case sensitive names) or not (so the plain name, without "", case insensitive, meaning casing is effectively ignored by the DB).

  • For DB2, the setting is called DB2CaseSensitiveNames
  • For Firebird, the setting is called FirebirdCaseSensitiveNames
  • For Oracle, the setting is called OracleCaseSensitiveNames
  • For PostgreSql, the setting is called PostgreSqlCaseSensitiveNames

The setting has to be specified in the application's app/web.config file in the appSettings section. If the setting is set to false or omitted, the default is used (false), which results in case sensitive names with all names being wrapped in "". If set to true, the names are not wrapped in "", and all "" wrapping characters are removed.