What's new/changed in LLBLGen Pro Runtime Framework v5.5?

Below you'll find a list of changes, additions and important fixes in the 5.5 release of the LLBLGen Pro Runtime Framework. It's recommended you also browse the Migrating your code section for breaking changes and how to migrate your current project with generated code to v5.5.

What's new in LLBLGen Pro v5.5

Below you'll find what's been introduced in LLBLGen Pro Runtime Framework v5.5

New functionality / changes

  • Insert / update query batching (Adapter). The runtime now supports batching of insert and update queries into single DbCommand objects which great helps with performance, especially when using a database over a connection with high latency, like a cloud database. Available for Adapter, on the databases SQL Server, PostgreSQL and Oracle. More information
  • Window specification support (OVER() clause)). The LLBLGen Pro Runtime Framework now comes with support for the SQL OVER() clause, which is used with window functions. OVER() allows aggregates and specific window functions to define a window in the resultset. This support is two fold: existing aggregate functions can be extended with an OVER() clause in the SQL query and new window functions like RANK() and FIRST_VALUE() are supported and can be specified directly in an LLBLGen Pro query together with an OVER() clause. More information.
  • Union / Union All support in Linq and QuerySpec. The LLBLGen Pro Runtime Framework finally gets support for a feature that has been requested for many times: support for UNION and UNION ALL in queries. For Linq, there's now full support for .Union() and .Concat() (the Linq equivalent for UNION ALL). For QuerySpec, the support comes in the form of two new methods: Union() and UnionAll(). More information: Linq, QuerySpec
  • Oracle is now supported on .NET Standard. Oracle has finally released a .NET Standard 2.0 compliant ADO.NET provider, and you can use the LLBLGen Pro Runtime Framework now with Oracle on .NET Standard supporting platforms like .NET Core 2.x. More information
  • Function mappings of functions with no arguments for Linq. Mapping a function which has no arguments, e.g. GetDate() is now supported for Linq (QuerySpec already did support this). This allows you to map a .NET method which doesn't accept any database originating elements to a database function. More information
  • Query / Optimizer hints for Linq / QuerySpec. It's now possible to specify a query hint or optimizer hint to help a database optimizer with a choice to make when optimizing a given query. Available for SQL Server, Oracle and MySQL. More information Linq, QuerySpec.

Small changes

  • IEntityCollectionCore.Clear(bool) has been added, where if the boolean argument is set to true, the entities in the collection are added to the RemovalEntitiesTracker collection of the IEntityCollectionCore instance (if present).
  • An EntityView(2) no longer issues a Reset with the ListChanged event when a field of an entity in the view changes however it has no effect on the order of the entities in the view. It only issues a Reset with the ListChanged event if the order changed due to the change of the entity field.
  • The BooleanNumeric type converter now supports float and double values as well for boolean. This means that a conversion from boolean will result in 1.0 and a conversion to boolean will be using Convert.ToBoolean(value).
  • An implicit conversion between Enum and string is now supported, besides the already supported implicit conversion between Enum and a numeric value (int/byte etc.). This means you can map an enum typed field onto a string based database field without a type converter. The conversion will use the ToString() method on the Enum instance to produce the string value when persisting an entity to the database.
  • Implicit numeric conversions between fields of type byte, sbyte, short, int, long, float, double, decimal are now supported without a type converter.
  • Introduced object name creation caching to avoid string concatenations which are repeated a lot of times per query. This both saves memory and some query creation performance.
  • ISortClause now has two new command chaining methods: SetCaseSensitiveCollation(bool) and SetEmitAliasForExpressionAggregateField(bool) which set resp. the CaseSensitiveCollation and EmitAliasForExpressionAggregateField flags and return the ISortClause instance again for command chaining.
  • ISortClause and ISortExpression now have an extension method ThenBy() which accepts an ISortClause and which is appended to the object it's called on. The ThenBy() method is in the QuerySpec namespace.
  • The Oracle DQEs for ODP.NET and MS Oracle now have a static flag, DynamicQueryEngine.AlwaysUseRowNumBasedPaging, which is set to false by default. If true, and compatibility is set to 12c, a paging query will use the classic rownum approach instead of the FETCH NEXT / OFFSET approach. The latter can be up to 40 times slower than the rownum approach (see: the JOOQ blog) so the classic rownum approach might be more efficient in your application than the new approach.
  • The Firebird DQE now has function mappings for DateTime properties Year, Month, Day, Hour, Minute, Second, MilliSecond, DayOfYear, DayOfWeek and the DateTime methods AddYears, AddMonths, AddDays, AddHours, AddMinutes, AddSeconds, AddMilliSeconds.
  • When a retrieval query is forced to perform client side paging, distinct filtering or limiting, it will now append resp. "Requires client side paging", "Requires client side distinct filtering" or "Requires client side limiting" when the ORMQueryExecution tracer is enabled and the level is set to 'verbose' (4).

What's new in LLBLGen Pro v5.4

Below you'll find what's been introduced in LLBLGen Pro Runtime Framework v5.4

New functionality / changes

  • Generated code is now much smaller, especially for Adapter. This leads to faster compilation times and faster code generation times (on top of the faster code generator in v5.4). A lot of code has been moved to the base classes EntityBase and EntityBase2. These changes have no negative memory impact nor performance impact, in fact memory consumption in prefetch paths is slightly better now.
  • The PlainSQL API now has a feature to perform implicit conversions of types, meaning a value of type T1 in the resultset can be implicitly converted to type T2 in the projection class, if an implicit conversion is defined for T1 and T2 (e.g. short to int)
  • Poco Typed List fetch methods in Linq and QuerySpec now have an optional query argument to be used as the root query, allowing you to specify a richer query than the generated query for the typed list.
  • PostgreSQL 10.x is now a supported database, which includes support for the new Identity fields in PostgreSQL 10.x
  • Empty methods for Field-mapped-onto-related-field event handlers are now avoided and code is less verbose
  • UnitOfWork and UnitOfWork2 now have a property IsEmpty which returns true if no work is scheduled in the unit of work instance. This property is also implemented in the interface IUnitOfWorkCore.
  • PostgreSql: the query generated for directly deleting entities using a join with another table now no longer uses non-ansi joins but uses a proper ansi-join using correlated subquery.
  • When fetching prefetch paths with a paging query, the runtime now automatically switches over to parametrized IN clauses for the prefetch path sub paths, no matter the value for the ParameterizedPrefetchPathThreshold. This avoids that all rows in the target of a sub path node are fetched and filtered on the client. This is now also done if a limit is specified for the root node and no paging is performed, the runtime in that situation now also picks the parameterized route.

It can lead to a crash if the page is too large, and too much parameters are issued for the sub path query. This is equal to the user setting the ParameterizedPrefetchPathThreshold to a value higher than the maximum amount of parameters allowed by the database. The solution to this is to use a smaller page size so the # of elements in a page is smaller than the max number of parameters for a database.

  • The PostgreSQL DQE now uses the RETURNING clause to return sequenced fields in an insert query instead of a separate scalar query which used a separate roundtrip; each insert query is always one roundtrip, even if there are sequenced fields involved.
  • SelfServicing: DeleteMulti/UpdateMulti and async variants are now virtual.
  • Using FetchProjection<T>(retrievalQuery) or FetchQuery<T>(plainSqlString) where T is a valuetype like Int32 or a system type like string, the query would fail in previous versions but will now succeed with returning a list of values (the values of the first column in the resultset), all typed T.

What's new in LLBLGen Pro v5.3

Below you'll find what's been introduced in LLBLGen Pro Runtime Framework v5.3

New functionality / changes

  • .NET Standard 2.0 support. The LLBLGen Pro Runtime Framework can now be used on .NET Standard 2.0 supporting platforms like .NET Core 2.0 and Xamarin. Please see the .NET Standard support page for details regarding the small amount of limitations you might run into.
  • New RuntimeConfiguration system to configure LLBLGen Pro Runtime Framework specific behavior and settings in code instead of in .config files. Mainly meant for .NET Standard 2.0 using applications but it's also available for .NET Full.
  • The Plain SQL API now has a FetchScalarQuery<T> method to retrieve a scalar value from the DB using a plain SQL query. More information.
  • Query tagging. Linq and QuerySpec have the ability now to let you mark (tag) the SQL query or queries generated by the runtime with a tag. This tag is a string which is added as a comment before the actual query string. This way you can easily track back the SQL query on a database server with the actual calling code without a profiler / stacktrace. It's a low-impact way to make sure you can track down information at runtime in the future. More information: Linq, QuerySpec.

Small changes

  • The Runtime Framework is now compiled against .NET 4.5.2
  • QuerySpec: When a scalar query is executed using FetchScalar<T> and T isn't a nullable type and the query returns a NULL value, the cast to T would result in a Null reference exception. We now added a check first which will throw an InvalidOperationException if a null value was returned and the type specified isn't a nullable type.
  • Lambda caches and factory caches are now using a ConcurrentDictionary instead of a Dictionary per thread, which should save some memory in large applications.
  • QuerySpec: an extension method has been added for ISortClause, DontEmitAliasForExpressionAggregateField, so the EmitAliasForExpressionAggregateField flag can be set using the fluent interface. See the LLBLGen Pro Runtime Framework Reference Manual for details.
  • A new exception class has been added: ORMConfigurationException. This exception is thrown when an error is detected in the RuntimeConfiguration usage.
  • Prefetch path fetches with a context are now using faster merges as the linear searches caused by the context usage in collections during merges are now no longer happening. This is done when the fetch is into a new graph. An existing graph will do the linear searches during merge as before.
  • Nuget: the packages for DQEs now reference a specific ORMSupportClasses version, which means you always have to update both when referencing a specific DQE package version. Previously we defined a range of [currentversion-nextmajorversion) but that is too large and causes 'downgrades' for .NET Core due to a change in the way downgrade warnings are handled by the .NET Core tooling.
  • Field compare value predicate now detects value truncation for variable string typed parameters. If it detects truncation, it will emit "1=0" instead of the actual predicate, followed by a comment to make the predicate result in 0 rows. Value truncation occurs if the DbParameter's Value property is set to a value which has a length longer than the 'size' property. The size property of the parameter is set to the length of the field compared against. So if you compare a varchar(20) typed field F to a string with length 25, you'll get 1=0 instead of the comparison of the first 20 chars of the string with the field, which could lead to matches which are unintentional.
  • Field value equality comparisons of byte array values are now more optimal.
  • Firebird 3.0 support. LLBLGen Pro Runtime Framework now supports Firebird 3.0. This effectively means that the new Boolean type is now fully recognized. The identity field support of Firebird 3.0 will be added as soon as the Firebird Client supports this.

What's new in LLBLGen Pro v5.2

Below you'll find what's been introduced in LLBLGen Pro Runtime Framework v5.2

New functionality / changes

  • Data Scope now has Async / Await variants of its methods so it can be used fully asynchronously.
  • A global flag has been added for SelfServicing to disable lazy loading with one setting: EntityBase.EnableLazyLoading. The flag is enabled by default (so lazy loading is enabled by default) for backwards compatibility.
  • Lots of string interpolation has been refactored to more efficient string usage, resulting in faster performance overall and even lower memory footprint/object pressure. LLBLGen Pro is now the fastest ORM, beating all microORMs too (using the plain sql API).
  • Size specification on Init() methods in the generated FieldInfoProvider and PersistenceInfoProvider classes have been removed, so merge conflicts will no longer occur when merging different code bases of generated code.
  • For new projects and projects which change the target framework to the LLBLGen Pro Runtime Framework, the default output type for TypedLists and TypedViews has been changed to PocoWithQuerySpecQuery. This was TypedDataTable. If you still want to use TypedDataTable as the outputtype for TypedLists and TypedViews, you can change the default in the LLBLGen Pro Runtime Framework settings in the Project Settings. The default choice is for QuerySpec and not Linq because typed views mapped onto stored procedure resultsets aren't supported in Linq but are supported with QuerySpec. For existing projects the old default is kept.
  • Linq/QuerySpec: Using 'Distinct' on a subquery which is used inside an 'IN()' clause is now used inside the subquery. This is due to an addition in the FieldCompareSetPredicate which now allows 'Distinct' in the subquery. For most databases the 'Distinct' in the subquery has no effect, but on e.g. Oracle it can help the optimizer to pick an index instead of doing a table scan.
  • AddCollectionForSave and AddCollectionForDelete are now part of IUnitOfWorkCore.
  • DataAccessAdapter.SaveTransaction(name) and Transaction.SaveTransaction(name) no longer throw an exception when name was already used within the same transaction, as all supported databases which do support savepoints support multiple savepoints with the same name in a single transaction so the check / limitation is unnecessary.
  • Entity field validation now doesn't report a precision overflow for decimals/floats/doubles with precision equal to scale and a value between (-1.0, 1.0) excluded. Even though the precision of a value in that interval, e.g. 0.55, is 3, the leading zero isn't taken into account by databases and therefore the runtime shouldn't either.

What's new in LLBLGen Pro v5.1

Below you'll find what's been introduced in LLBLGen Pro Runtime Framework v5.1

New functionality / changes


  • Easier projection definitions. It's now easier to define a projection to a POCO when you want to specify a set of fields in a Select. More information: Projections in QuerySpec


  • Temporal (History) Table support:. For SQL Server 2016 and higher/ DB2, temporal tables are now supported through Linq / QuerySpec (Select / fetch queries only). Temporal tables are an easy, friction free way to store previous versions of modified / deleted rows in a table. The temporal table support in LLBLGen Pro allows you to include older versions of entities when querying. More information: Linq, QuerySpec
  • Hints support. For SQL Server / MySQL, select target hints are now supported through Linq and QuerySpec. More information: Linq, QuerySpec
  • Plain SQL API. You can now execute plain SQL statements using parameters directly onto the database, including fetching resultsets and projecting the resultsets to POCO classes. With this API you don't need a microORM on the side anymore for those situations where the runtime couldn't give you the right query. This API is also very fast: fetching a query through this API is faster than most microORMs. See: Results from 21 September 2016. These results were determined using RawDataAccessBencher. More information: Plain SQL API.
  • Easier projections from stored procedures. It's now easier to create projections of stored procedure resultsets onto POCO classes, all it takes is specifying the target type. More information: Adapter, SelfServicing

What's new in LLBLGen Pro v5.0

Below you'll find what's been introduced in LLBLGen Pro Runtime Framework v5.0

New functionality / changes

  • Linq: It's now possible to use Union() in the last projection in the query (the most outer projection). The Union() call is not executed in the database but in the projection code itself. Using Union() elsewhere in the query will still lead to an error as Union() isn't supported in LLBLGen Pro queries.
  • IDataAccessAdapter.KeepTrackOfTransactionParticipants has been added. The flag (default true) is used to signal the adapter that entities participating in a transaction controlled by this adapter are tracked during the transaction and which values are rolled back after a rollback of the transaction itself. Only set this flag to false if the entities participating in a transaction are not kept in memory during or after the transaction's life time.
  • Queries using projections in Linq or QuerySpec are now 30-40% faster than in v4.2 and are in general faster than a lot of the existing MicroORMs. See: https://github.com/FransBouma/RawDataAccessBencher, results from December 16th, 2015.
  • QuerySpec now defines a CaseInsensitive extension method for FieldCompareValuePredicate to set it into CaseInsensitive mode:
    IPredicate p = CustomerFields.CompanyName.Equal("Foo Inc").CaseInsensitive();
  • QuerySpec now defines a CaseInsensitive extension method for ISortClause to set it into CaseInsensitive mode:
    ISortClause s = CustomerFields.CompanyName.Descending().CaseInsensitive();
  • Various changes in the Linq provider to make it more robust.
  • The static variable EntityCore.MakeSettingNonNullableFieldsToNullFatal has been added (default: false, for backwards compatibility), to make setting a non-nullable field to null throw an ArgumentOutOfRangeException.
  • SQL Server 2016 is now a supported database (through the SQL Server DQE/templates). Use 2012 compatibility to utilize the 2012 or higher features.

What's new in LLBLGen Pro v4.2

Below you'll find what's been introduced in LLBLGen Pro Runtime Framework v4.2

New functionality / changes


  • Allowed Action Combinations: Specify which actions are allowed on an entity instance: Any combination of Create/Read/Update/Delete. Action Combinations make it easy to define e.g. entities which can only be created or read but never updated nor deleted. The action combinations are defined at the mapping level and checked inside the runtime and are additional to the authorization framework. More information...
  • Expression support during Inserts It's now possible to define an expression on an entity field which is used during inserts. The expression defined is used to produce the field value. More information...
  • Generate Typed Lists as POCO classes with a Linq or QuerySpec query. It's now possible to generate a typed list or all typed lists (controllable through settings) as a simple POCO class which holds the data of a row in the resultset and a Linq or QuerySpec query to execute the typed list. Adapter, SelfServicing
  • Generate Typed Views as POCO classes and use them in Linq and QuerySpec. It's now possible to generate a typed view or all typed views (controllable through settings) as a simple POCO class and use it in Linq or QuerySpec queries. Adapter, SelfServicing
  • Transparent Transient Error Recovery (adapter only). The transient error recovery system introduced in v4.1 has been upgraded so it can now be used transparently: define once and it is automatically used when executing a query. It's no longer necessary to explicitly execute a query through a recovery strategy. More information...
  • Cached resultset tagging for easy cache purge/retrieval It's now possible to tag a query's resultset if that resultset is cached so the resultset can be retrieved from the cache using the tag and also it's now possible to purge the resultset(s) associated with the tag from the cache. More information...
  • Exclude prefetch path nodes from resultset caching. It's now possible to exclude a prefetch path node from being cached if the root query has a resultset caching directive. More information...

Small changes / fixes

  • QuerySpec: Multiple calls to query.From(operand) are now appending the operand to the existing From clause if operand starts with QueryTarget. If it doesn't start with QueryTarget and there's an existing From clause, it will overwrite the existing From clause.
  • OData: The OData Support Classes now support the IgnorePropertiesAttribute on entity classes. The names specified using the attribute have to be defined on the entity type the attribute is defined on, so inherited properties can't be filtered out using this attribute.
  • Low level api: Duplicate sort clauses are now filtered out so accidentally added duplicates through e.g. OData are no longer causing exceptions at runtime.
  • Dynamic Query Engines: when the source of a field isn't known, the field creator functionality will no longer emit a dangling . but will simply only emit the field name/alias. This way constucts like .OrderBy("Name".Ascending()) will work, where the engine will emit ORDER BY [Name] ASC. Previously the above construct would result in ORDER BY .[Name] ASC which would fail.
  • Query traces: The value of a parameter of type DateTime value in a query is now emited as a ISO 8601 / Roundtrip formatted string, which is more precise than the previous ToString() call on the DateTime which didn't include fractions of a second.
  • FunctionMappings added (Linq/QuerySpec): sbyte/byte/ushort/short/uint/int/ulong/long.ToString() mappings have been added to all DQEs for all databases.
  • EntityBase(2).AllowReadsFromDeletedEntities allows code to read from an entity that has been marked as deleted. It's been set to 'false' as the default which will result in an exception if code reads from a deleted entity, like in previous versions.
  • SQL Server 2014 is now a supported database (through the SQL Server DQE/templates). Use 2012 compatibility to utilize the 2012 or higher features.
  • Catalog name is now supported in sequence name, if applicable. In SQL Server, a catalog name can be present in the sequence name, and should be overwritten if required. In previous versions, the catalog name was ignored, only schema names were supported with a sequence name.
  • FIX: QuerySpec: A projection lambda was created using a parameter which was created for every new query, which resulted in a new cache key for the lambda so the lambda was compiled every time instead of re-using a cached version. The lambda is now created using the same parameter as the original and the compiled version cached is re-used in subsequential executions of the same projection so query creation is a bit quicker.
  • FIX: QuerySpec: QuerySpec doesn't properly replace function mappings in derived tables. Queries like the following now work:

    var qf = new QueryFactory();
    var qs = qf.Create("S")
    var q = qf.Create()
                .Select(qf.Field("S", "YearOrder"))
  • QuerySpec: There's now a class available to create a projection lambda quickly for Select<T>() calls, called ProjectionLambdaCreator. This class has two overloads of its Create() method which creates at runtime a projection lambda for T from either a specified fields set or a fields creation class (e.g. CustomerFields). The overload which accepts the fields creation class caches the created lambda and is therefore much faster than a lambda created in code and compiled by the C# / VB.NET compiler which will create a new Expression<Func<T>> at runtime each time it is run.
    var qf = new QueryFactory();
    var q = qf.Create()
                .Select(ProjectionLambdaCreator.Create<OrderPocoQsRow, OrderPocoQsFields>())
                .Where(OrderPocoQsFields.CustomerId == "ALFKI");            
    Here, the ProjectionLambdaCreator creates a lambda for the OrderPocoQsRow, which is equal to the code below which was what you had to write in v4.1 and earlier:
    // equivalent code, prior v4.2
    .Select(() => new NW26.Adapter.TypedViewClasses.OrderPocoQsRow()
        CustomerId = OrderPocoQsFields.CustomerId.ToValue<System.String>(),
        EmployeeId = OrderPocoQsFields.EmployeeId.ToValue<Nullable<System.Int32>>(),
        Freight = OrderPocoQsFields.Freight.ToValue<Nullable<System.Decimal>>(),
        // etc. all fields specified.
    The advantage is that the ProjectionLambdaCreator call caches its lambda under the two types specified while the written out lambda creation code will create a new one each time it is run. Running the code about 100,000 times takes 98ms for the ProjectionLambdaCreator and 19832ms for the written out code, so it does make a difference.
  • QuerQuerySpec: There's now a special Select method available which produces its own lambda projector from two types given:
    var qf = new QueryFactory();
    var q = qf.Create.Select<SomeDTO, SomeElementFields>();           
    This method, dynamicQuery.Select<T, U>() creates a projection and projector lambda from T and U for dynamicQuery and makes it a DynamicQuery<T>. The type T is the type of a class which instances are returned by the created DynamicQuery<T>, and can be an entity type or DTO or e.g. generated typed view type. The type U is the type of the generated helper class which creates the fields for T, e.g. CustomerFields.
  • QuerySpec: The usage of QueryTarget is now also supported in DynamicQuery / DynamicQuery<T> instances, but only in appending join operands to an existing query:
    var q = qf.Create()
  • QuerySpec. you don't need to create a new field for each targeted subquery field anymore, if you want to effectively clone the projection of a subquery. It's now possible to clone a projection of a derived table/aliased subquery in an outer query's Select() method.
  • It's now possible to generate case insensitive SQL for case sensitive databases using a setting.

What's new in LLBLGen Pro v4.1

Below you'll find what's been introduced in LLBLGen Pro Runtime Framework v4.1

New functionality / changes


  • Full async API. The runtime framework now offers a full Async API, usable in Linq, QuerySpec and the Low-Level API for retrieval of data and object persistence. Usable in async/await code on .NET 4.5 and higher. More information...
  • Transient Error Recovery The runtime framework now offers the ability to recover from transient errors occuring during database activity. More information...
  • Oracle 12c support The runtime now supports Oracle 12c: Identity/default sequences are now supported on Oracle 12c as well as the new paging keywords for SELECT on Oracle 12c.
  • Managed Oracle ODP.NET provider support The runtime now supports the managed ODP.NET provider for Oracle (v12+ of ODP.NET).


  • The default for the designer setting TdlEmitTimeDateInOutputFiles has been changed to false.
  • LinqMetaData now has an overload of GetQueryableForEntity: GetQueryableForEntity<TEntity>(), which accepts a generic type and returns a DataSource(2) object for the given entity type.
  • If a sequence retrieval query(fragment) returns null before/after an insert, due to wrong sequence semantics or the field isn't marked as identity in the database while the mapping code defines it as a sequenced field, an exception of type ORMBadSequenceException is now thrown. The exception contains the query executed.
  • CachingController now has a static public field, CachingEnabled (default true), which controls whether the caching controller caches resultsets (true, default), or silently doesn't cache any resultsets (false). Useful when debugging code which otherwise would cache the resultset. 
  • To QuerySpec the fluent extension method IEntityRelation.SetCustomFilter(..) (2 overloads) has been added to easily set a custom filter on a relation specified in a queryspec query. This extension method, as most QuerySpec extension methods, is also usable with the low-level API.
  • Adapter now has a new method on entities: DetachFromGraph. This method will detach the entity it's called on from its referenced entities, including m:n relations. It will only dereference from the entities it knows of at runtime.
  • BREAKING CHANGE: Multiple .Take() calls on a query in Linq will no longer result in 'last Take wins' but will use the lowest number of the Take calls.
  • BREAKING CHANGE:OData Support Classes are now build against WCF Data Services 5.6.0.

What's new in LLBLGen Pro v4.0

Below you'll find what's been introduced in LLBLGen Pro Runtime Framework v4.0

New functionality / changes


  • 50% faster entity fetches. An extensive refactoring of the internal storage of values inside an entity instance resulted in up to 50% faster entity fetches. As entity instances don't have Entity Field instances to store their values anymore (though from the outside it will appear they will, so no code will break), memory footprints are smaller too. See http://pastebin.com/AdsKitr3 for a benchmark of how much faster the fetches are compared to v3.5 and other ORMs. 
  • Extensible Query Result Caching. It's now possible to specify (in Linq or QuerySpec, and with minor effort also with low-level API calls) a query result cache directive to tell the runtime to cache the results for that particular query for a given amount of time. The caching system is build around an easy interface, making it easy to extend it with own cache providers for cache systems like Redis. More information...
  • Table Valued Function support. It's now possible, using Linq and QuerySpec, to fetch entities and typed views which are mapped onto a table valued function resultset.  Linq, QuerySpec
  • DataScopes. The runtime framework now offers DataScopes which greatly help managing data in memory in desktop applications.  More information...
  • Runtime Libraries are now compiled against .NET 3.5. The minimum .NET version supported by the runtime framework is now .NET 3.5.
  • LinqSupportClasses and QuerySpec assemblies are now merged into ORMSupportClasses. The 3 assemblies are now merged into one, SD.LLBLGen.Pro.ORMSupportClasses.dll. This makes referencing assemblies simpler.
  • Inlining of Value Type Definitions in the designer. It's now possible to in-line value type definitions in the designer, which makes modeling LLBLGen Pro projects simpler. More information...
  • SQL Server 2012 sequences support The runtime framework now supports SQL Server 2012 sequences in insert queries.
  • TypedLists can now be fetched using QuerySpec. Before, the low-level API had to be used to fetch typedlists. In v4.0 we made it possible to fetch TypedLists using the more powerful QuerySpec query API.
  • True skip/offset support. It's now possible to skip n rows in a fetch without the requirement that the number of rows fetched is a multiply of n. This is in line with how Skip works in Linq. QuerySpec now has a new operator, Offset(n) which offers the same functionality.
  • Char <-> String(1) built-in type converter. The runtime framework now has a built-in type conversion for char <-> string(1), to make it possible to have a DB field of type char(1) be used as a .NET char typed field.
  • Support for OData v3. The ODataSupportClasses now support OData v3 and are now compiled against WCF Data Services v5.3.
  • QueryExecution Tracer. A new tracer has been added, to trace the actual query being executed. This information was already available through other tracers, but as these also emitted other information it could lead to a lot of data just to see which query was actually executed. This tracer solves that.
  • All low-level query API elements, including UnitofWork2, are now XML Serializable. All low-level query API classes, like predicates, relation collection, groupby collection but also the Unit of Work classes, are now serializable to XML, and as such passable to e.g. a WCF Service. This is for Adapter only.


  • SourceFieldFinder. The SourceFieldFinder is now a public class so it can be used to traverse entity graphs in user code.
  • Better name length clamping in DB2 and Oracle DQEs. Names were already limited to 30 characters or less for DB2 and Oracle, but in some edge case queries with nested derived tables it could be the field inside a derived table was clamped to a shorter name, but a field referencing it wasn't. Name clamping now uses F__hashcodeOfStringToClamp which is not depending on field index anymore.
  • The runtime assemblies are now stored all in one folder. In previous versions the runtime library assemblies were stored in different folders, based on the .net version they were for. This is not needed anymore, so all files are stored in one folder.
  • DbCommands are now, when possible, created from DbConnection. This makes it easier to add functionality like the miniprofiler to the generated code.
  • DataProjectorToDataTable now creates columns from projectors. This change has the advantage that if the resultset to project has 0 rows, the columns in the datatable are still created.