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

Below you'll find a list of changes, additions and important fixes in the 5.0 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.0.

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

General

  • 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")
                .Select(DateTimeFunctions.Year(OrderFields.OrderDate).As("YearOrder"));
    var q = qf.Create()
                .Select(qf.Field("S", "YearOrder"))
                .From(qs);
    
  • 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.
    Usage:
    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()
                .From(qf.Customer.InnerJoin(qf.Order)
                .On(CustomerFields.CustomerId.Equal(OrderFields.CustomerId)));
    //....
    q.From(QueryTarget.InnerJoin(qf.OrderDetails)
            .On(OrderFields.OrderID.Equal(OrderDetailFields.OrderId)));
    
  • 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

General

  • 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).

Changed

  • 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

General

  • 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.

Changed

  • 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.

Fixed