Visual Designer: Batch Operations Dialog - The users are now able to perform refactoring operations on multiple items from a domain model. For example, classes or properties can be renamed with a single operation. Changing the most commonly used properties of classes and members like Namespace, Key Generator, CLR type, etc. is also possible in an automated manner. Additional search functionality has been implemented to allow quick filtering and location of domain model items. Support for easily renaming classes and properties in a grid like manner is also added.
Visual Designer: Support for fluent mapping code generation has been added for the Visual Designer.
- Fluent mapping has been added as the third option for mapping definition with the Visual Designer, besides Xml and Attributes.
The existing template for fluent mapping code generation used by the "Upgrade to Domain Model" Wizard,
has been re-used in the Visual Designer.
Context API enhancements - The OpenAccessContext did not expose certain functionality that is available via the IObjectScope interface and via the Database class. This includes operations like flushing a transaction, explicitly beginning and committing a transaction, evicting that L2 cache etc. All such relevant functionality has been exposed via the OpenAccessContext.
context.FlushChanges()
context.Events...
context.GetState(customer)
context.DisposeDatabase()
context.ReadOnly = true;
context.HasChanges
context.Cache...
context.LevelTwoCache...
Profiler: Save functionality for live data profiling. - A user is now able to store his profiling session and open it for review later.
Project Template: The Fluent Class Library templates should contain code that can update a database schema - The sample context that is generated is now enhanced with common code for creating and updating a database schema.
NuGet: The sample package should contain code that can update a database schema - The sample context that is generated is now enhanced with common code for creating and updating a database schema.
LINQ: Support for FetchStrategy settings per LINQ query - When a LINQ query is executed, a FetchStrategy can now be set by the user.
Previously, the context instance has a FetchStrategy, but this strategy can now be overridden on a per-query base.
Example:
var q = context.GetAll<Northwind.Order>().Include(p => p.OrderDetails).Where(m => m.Id == 10249 || m.Id == 10250).Take(3);
var q = context.GetAll<Node>().Include(e => e.Parent.Parent.Parent.Parent.Parent.Parent.Parent);
var q = context.GetAll<Node>().Include(e => e.Children.Select(f => f.Children.Select(g => g.Children.Select(h => h.Children.Select(i => i.Children)))))
LINQ: Support for IQueryable<InterfaceType> added for right sides of Queryable.Join() -
When a class Product implements an interface IProduct, an extent of that class (like context.AllProducts) can be used as
IQueryable<IProduct> by calling context.AllProducts.OfType<IProduct>().
LINQ expressions can then be formulated with the properties that the interface provides. Support has been added so that an IQueryable<IProduct> can be used as the joined (right side of a Queryable.Join()) expression:
from od in context.AllOrderItems.OfType<IOrderItem>()
join p in context.AllProducts.OfType<IProduct>()
on od.ProductId equals p.ProductId
select new { ... }
Runtime: Background Threads error handling - OpenAccess executes background threads for level 2 cache synchronization, storing log files and closing busy connections. Those threads were not writing all errors or exceptions they get into log files. This used to make it hard to understand how OpenAccess works and had to be changed.
Whenever an error occurs in such a thread, this error can be ignored if necessary to not stop the application execution but is now reported with the actual enabled log mechanism(s).
To detect that those threads are running and with which setup, the start of all threads should be reported in logging mode 'Verbose'.
Runtime: Support for logging events in the Windows Application Event Log - Errors can be logged now into the Windows Application Event Log. You have to turn on this feature using the backend configuration:
be.Logging.LogErrorsToApplicationEventLog = true;
Schema Read: Performance improvements for the schema read process - The performance for the schema read process is now improved. Now it is using optimal and minimum amount of queries to obtain required schema metadata information.
Stored Procedure support: Oracle stored procedures that return result sets can now be executed via a generated domain method. - The 'Stored Procedure Editor' provides the ability to generate a method, in the context class, for a stored procedure in order to execute it. If a stored procedure returns a result set(s) the editor can be used to create a CLR type with properties that map to the columns returned in the result set.
Oracle stored procedures return result set(s) via an output REF CURSOR parameter. It is now possible to obtain the result set shape for such stored procedures and map them to existing persistent type(s) or generate a new CLR type to hold the result set.
Generic Data Access: A new extension method has been provided method for setting field values for persistent objects - Provide a SetFieldValue<T> extension method that can be used for setting field values. Together with the FieldValue<T> extension method it is now much easier to work with artificial fields.
Fluent: Support for defining relational items for artificial associations - Support has been added for defining relational items for one-to-many and many-to-many artificial associations. The .ToColumn() and .MapJoinTable(...) can now be used after specifying an artificial association.
Fluent: Support for specifying indexes over columns in a base horizontally mapped class. - An index can be defined over all properties in a horizontally mapped class as they are all stored in a single table, currently this is not possible through the HasIndex API.
Fluent: Support for specifying the field name of dictionary and array properties - The .HasFieldName(string) overload has been added for properties of type Dictionary<TKey, TValue> and Array properties.
Fluent: Using IsVersion() or HasVersion(...) should automatically set the concurrency control to Version. - When either HasVersion or IsVersion is used in the mapping configuration of a type, the Fluent Mapping API now automatically infers that the concurrency control is set to Version.
Installer: A new Getting Started guide added to the installer - A new Getting Started guide is added to the installer and a shortcut for it is placed in the start menu.
SDK New Example: Data Binding with OpenAccessLinqDataSource - The old OpenAccessDataSource example is replaced by a new OpenAccessLinqDataSource example, presenting RAD data binding using the new LINQ-based OpenAccess component.
SDK New Example: Kendo UI integration with a WCF Data Service - A new example is added to demonstrate the integration between Telerik OpenAccess ORM and Kendo UI. The example is based on a WCF Data Service that exposes the entities using JSON and provides support for JSONP. The Data Service is consumed by a Kendo Data Source, presenting data in a Kendo Grid.
SDK New Example: Sofia Car Rental MVC3 Razor with Fluent Mapping - A new Sofia Car Rental MVC 3 example is added to the SDK, presenting a full blown ASP.NET MVC 3 (using the Razor view engine) application developed to show the best practices in implementing MVC applications using the Fluent Mapping approach.
SDK New Example: Sofia Car Rental MVC3 Web Forms with Domain Model - A new Sofia Car Rental MVC 3 example is added to the SDK, presenting a full blown ASP.NET MVC 3 (using the old Web Forms) view engine application developed to show the best practices in implementing MVC applications using the Database-First mapping approach.
SDK New Example: Sofia Car Rental MVP - A new ASP.NET example is added, demonstrating the best practices for integrating OpenAccess ORM in Web Forms MVP applications.
SDK New Example: Managing OpenAccess Context - The two best practices examples for context handling in a web environment have been improved and merged into one.
SDK: Sofia Car Rental Web site sample is enabled for profiling - The SofiaCarRental Web Site application is configured to support online profiling.
SDK: Sofia Car Rental Win Forms Sample is improved - The "SofiaCarRental - WCF Plain Services with WinForms" example is updated. It uses the latest version of the RadControls for WinForms. The example is refactored to follow the design principle of loose coupling. In addition, there is an entirely new Data Access Layer that uses our best practices in dealing with WCF services, i.e. UnitOfWork, DTOs, Assemblers and Repositories. The presentation logic and the data access layer are fully covered by unit tests.
Fixes
ADO API: Execute Scalar method throws cast exception - When the OADataReader returned DBNull as result the ExecuteScalar method was unable to cast it and a CastException was thrown.
Association Editor: Pluralization issue with navigation property names in many-to-many associations. - When a many-to-many association is configured in the relational view, the property name of the source end was in singular form instead of plural.
Association Editor: A validation error was incorrectly shown when there was a mismatch between the nullability of the foreign key and identity column.
- Validation error was thrown in case a user tried to add an association between two classes where the foreign key column is nullable and the primary key column is not nullable.
This is a valid scenario and the validation has been improved for such cases.
Association Editor - when 'Target End' is unchecked the validation for its name was still executed.
- Association Editor - Object View: typing incorrect symbols like '@#$%^ in Target End TextBox resulted with an error indicator.
Unchecking 'Target End' did not remove the validation error indicator.
Association Editor: When the association name is edited and the target (or source) table is modified, the association name will be reset. - The user input for the association name now prevails over the calculation that occur when the target or source class or table is changed.
Attributes Mapping: NullReferenceExpection can be thrown when an internal property is added in a partial class of the generated context. - The AttributesMetadataSource can now handle customizations made to the generated OpenAccess context by the users.
Cannot generate a service in a web application that contains a packages.config - The packages.config file that is used by NuGet was picked up as a regular configuration file by the new "Generate OpenAccess Data Service..." wizard which lead to an exception in the generation step of the wizard.
Code generation: Using (Imports) directives are not always generated properly when generating code into a single file. - The default namespace is not included in the generated using (Imports) directives when the code is generated in a single file. This may lead to unresolved type errors for classes in a non-default namespace.
Context: Wrong values reported by ContextChanges.GetInserts() when adding and deleting the same data within the same context. - Following the change tracking example in the documentation http://www.telerik.com/help/openaccess-orm/openaccess-tasks-working-with-objects-get-changes.html, the Telerik.OpenAccess.ContextChanges.GetInserts() method reports 2 objects to be inserted. Since they are also deleted within the same context instance, the count of the inserted objects should be 0.
Convert To Domain Model: Converting a model that contains base classes from another assembly fails. - This exception was thrown due to the fact that the wizard lacked assembly resolution mechanisms and could only load the needed assembly if it is in the GAC.
Entities not shown in the RIA wizard when the default namespace is changed. - When changing the default namespace of one Domain Model it is possible that the entities that remain in the "old" default namespace will not show up in the RIA wizard.
Fluent Code Generation: Generation of property configurations for Enum properties results in uncompilable code for Visual Basic. - Calls to generic methods in Visual Basic are now generated with explicit casts, this has resolved issues related to method overload resolution for HasProperty(...).
Fluent: HasConstraint expressions not resolved when the compared types are mismatched. - When using expressions like .HasConstraint( (x, y) => x.ShortProperty == y.NullableShortProperty) could not be parsed due to multiple convert expressions being constructed.
Fluent: If the first non-horizontal class in an hierarchy is marked as either Flat or Vertical derived properties mapping can be lost. - The mapping information for a class marked with Flat and Vertical that is also the first non-horizontal class in an hierarchy can be lost.
Fluent: ReferenceID values are now correctly produced - If a reference is not mapped additionally by a shared field,
the underlying id value is not read as part of the default fetch query.
Fluent: Specifying a custom TypeConverter for a DateTime or string field via the 'WithConverter<T>' method throws a TypeLoadException
- Using the Fluent API a custom type converter implementation can be used for a primitive member of a persistent type.
This converter can be set via the 'WithConverter<T>' method of the DateTimePropertyConfiguration or StringPropertyConfiguration type.
If a converter is set a type load exception with the following message, is thrown. - 'Could not load type <T> from assembly 'Telerik.OpenAccess.Runtime'"}'
Fluent: Specifying HasLength(0) results in null length in the produced MetaColumn - Specifying HasLength(0) is a valid scenario and should produce a Length of 0 in the MetaColumn.
Fluent: Support for navigation properties of type TrackedList - If the model contains TrackedList<T> as persistent collections, the fluent mapping could not be used. Null reference exceptions were thrown if such a mapping was specified.
Fluent: Two sided arterial associations defined on a non-artificial type not working - When defining an association using HasArtificialAssociation(string, Type).WithOpposite(string) on a type that is not persistent the enhancer used to throw a FieldNotFoundException.
Fluent: Constraint names not generated properly for associations between the same two classes - When two associations are defined between the two classes (for example Order and Customer) using the HasConstraint((x, y) => x.CustomerId == y.Id) a single association was created with name FK_Orders_Customers instead of two.
LINQ: Comparison of reference type parameter with null in the filter condition can throw an exception - When a reference type parameter is compared with null (or null is on the right side), the client side calculation used to throw an exception.
Workaround: Rather with null, compare with a new object instance, which will also produce false when evaluated on client side.
LINQ: Conditions on joined extents can throw exception during compilation under specific circumstances - When a condition is placed on a joined extent iterator and that condition is translated with a copy of the internal query representation for that iterator, there might be an exception 'Invalid subquery' or invalid SQL is generated ('multi-part identifier could not be bound').
LINQ: Handling of entity.boolField.Equals(boolValue) not equivalent to entity.boolField == boolValue, failing with invalid SQL
- When entity.boolField.Equals(boolValue) is used, incorrect SQL is produced.
Workaround: Use entity.boolField == boolValue instead.
LINQ: Improved support for the let keyword - Support for the let keyword has been improved so that normal use cases are handled.
LINQ: Intermediate simple interface cast not working, leading to an exception - When a persistent class queryable is cast to an implemented interface, an exception occurred during query compilation.
Example: context.Persons.Cast<IPerson>().Where(p => p.Age > 42).ToList();
LINQ: Join on an already joined/grouped/projected right side not detected correctly, leading to InvalidOperationException
- When a non-trivial right (already grouped,joined,projected) side has to be joined, the join must happen in memory.
The transition was not correctly detected, leading to InvalidOperationExceptions.
LINQ: Multiple conditions in a where clause are now working when using properties of other objects as filtering conditions - A sample of a non-working query:
Employee emp = new Employee { FirstName = "Nancy", LastName = "Davolio" };
Employee employee = context.Employees.Where(e=>emp.FirstName.Equals(e.FirstName) && emp.LastName.Equals(e.LastName)).FirstOrDefault();
As Workaround use:
Employee emp = new Employee { FirstName = "Nancy", LastName = "Davolio" };
string fName = emp.FirstName;
string lName = emp.LastName;
Employee employee = context.Employees.Where(e=>fName.Equals(e.FirstName) && lName.Equals(e.LastName)).FirstOrDefault();
LINQ: Projection of referenced nullable base type fields can yield default value instead of null - When a projection is made like 'from x in context.Employees select { a = x.ReportsToID, b = (int?)x.ReportsTo.ID }', the result can contain different values for a and b: a = null and b = 0.
Workaround: Use 'from x in context.Employees select { a = x.ReportsToID, b = (x.ReportsTo == null ? null : (int?)x.ReportsTo.ID) }'
LINQ: Resolution of lambda parameters can fail with ArgumentOutOfRangeException when same source expression is used a second time in the LINQ expression tree. - When a common IQueryable<T> is used a second time in the same LINQ expression tree and this queryable has a condition specified, the same parameter expression instance is used a second time, leading to an inner exception that is potentially hidden by an outer StackUnderflowException.
Workaround: Avoid using the exact same source (with conditions) a second time. Express the same condition a second time with a differently named parameter expression.
LINQ: Sum of Sums statements are now working properly - LINQ queries that contain sum of sums aggregates are now working as expected.
LINQ: Using an already joined and projected iterator can lead to exceptions during compilation of the query - When the right side of a LINQ Join() is already a projected join a NotSupportedException can be thrown.
LINQ: Using nested Any() expressions can lead to exception when SQL is generated - When an expression of kind context.Customers.Where(o => !o.Orders.Any(d => d.OrderDetails.Any())).OrderBy(c => c.Id).Select(c => c.Id); is encountered, the handling of the inner sub-expression can yield an exception.
LINQ: When OfType<X>() is used, the following expression parts cannot resolve the new type X which can lead to exceptions when accessing X fields.
- When an expression like ctx.Persons.Where(p => p.Age > 20).OfType<Student>().Where(s => s.Grade == 'A') is given,
the resolution of Grade will fail.
LINQ: When Take()/Skip() comes before Select(), the resulting query is not paged - When Take() or Skip() is written before Select(), the resulting SQL is not taking the paging into account, potentially delivering more than expected.
Workaround: Perform Select() before Take() or Skip().
LINQ: When using .NET 3.5, intermediate anonymous type members and properties are represented by their getter. This can lead to wrong SQL compilations or compilation errors for unresolvable FieldAliases - When an anonymous type is generated (for example during projection of src1.Join(src2, keySel1, keySel2, (a,b) => new { a,b })), the members of the anonymous type are represented by their getters in 3.5, but .NET 4.0 uses PropertyInfo instances. This can lead to the situation where the wrong member is chosen for further processing, causing wrongly generated SQL or (more likely) non-compilable LINQ ('FieldAlias not found').
LINQ: Intermediate simple interface cast can lead to an exception - When queryable of a persistent type is casted to an implemented interface, an exception occurs during query compilation.
Example: context.Persons.Cast<IPerson>().Where(p => p.Age > 42).ToList();
Model Details Editor - Inheritance mappings: Discriminator column was set to <None> by default when Vertical Inheritance is defined, but a default discriminator column was actually created in the database schema. - When Vertical Inheritance is defined, the default selected value in the Discriminator Column combo-box was <None>, indicating that no discriminator column will be created for this hierarchy in the database. The runtime however was creating a voa_class column, which is the default behavior for any inheritance mapping. If a user does not want a discriminator column in the database, the <None> option should be explicitly selected. When the inheritance is created however, there is now an additional setting <Default> which indicates that a default voa_class column will be created by the runtime for this inheritance strategy.
ObjectNetworkAttacher does not work with new mappings - If the ObjectNetworkAttacher was used with fluent mapping or rlinq file, all persistent types were not detected and an exception is thrown. The ObjectNetworkAttacher can now be used in a context by adding these method to the context class:
public object Attach(object objectToAttach)
{
return ObjectNetworkAttacher.AttachXML(GetScope(), objectToAttach);
}
The ObjectNetworkAttacher source (found in the OpenAccess \src directory) must be included as well.
ODataService: SQL generation error when more than one condition is given in a filter - When a filter condition consists of more than one part (in other words, an AND or OR was used), the generated SQL was not executable on the database server.
OpenAccessContextBase.Translate<T> does not reliably detect an already closed DbDataReader - The OpenAccessContextBase.Translate<T>(DbDataReader reader) returns a lazily evaluated IEnumerable<T>. When an actual enumerator is requested, the reader can be already closed. This circumstance is now reliably detected and an exception is thrown.
PostgreSQL: Reading the database schema can fail with duplicate key exception - Reading the database schema for a PostgreSQL database can fail with a duplicate key exception. It happens if unnamed stored procedure parameters are used.
Runtime: Base table join missing in some case of vertically inheritance - If a class hierarchy is mapped vertically and the base type field under a reference is located on the base class, the join to the base table was missing. The result is an invalid SQL statement.
Runtime: Invalid parse of a Scope.GetSqlQuery when the query starts with a new line - When calling the Scope.GetSqlQuery method with a SQL that has a carriage return before the word select, we assume that we have a stored procedure, which will cause the fail of a simple select statement.
Runtime: CLR and ADO type Default Mapping not used - If a special type mapping is defined in the metadata container, this was not used during runtime. Example:
metadataContainer.DefaultMapping.ClrMap.Add(new Telerik.OpenAccess.Metadata.Relational.DefaultTypeMapping() { ClrType="System.String", AdoType = OpenAccessType.Varchar, SqlType = "nvarchar", UseDefaultMapping=true });
Workaround: the mapping can be set at each string field directly.
Runtime: Flush does not update concurrency control information - If an object with concurrency control changed is flushed twice to the database a optimistic concurrency control exception is thrown. This is caused by Flush optimizations. Workaround: Use FlushAndUnmanage() instead of Flush().
Runtime: Implement a type converter that can write GUIDs always in upper/lowercase - In some situations it might be required to write GUIDs always in upper/lowercase letters to the database. Therefore we created the new converters "String2UpperGuidConverter" and "String2LowerGuidConverter".
Runtime: Wrong SQL when using string literals with question marks - When string literals are used from LINQ or OQL, and those literals contain question marks, the generated SQL was invalid.
Runtime: Vertical mapped class hierarchy produces now produces fewer join statements -
If a class hierarchy is mapped vertically, a query to a base class contains all joins to all derived classes tables regardless
if data from those tables is required. Those joins can now be avoided by removing all derived class fields from the default
fetch group or set their load behavior to Lazy.
Schema Read Oracle: Stored procedure with same name - Oracle can have Stored Procedures with the same name in the same package. OpenAccess could not distinguish between them and creates one procedure that has all parameters.
Schema Read: Tables or procedures that have the same name as a system schema are not read. - OpenAccess ORM failed to read tables or procedures that have the same name as a system schema. For example: In MS SqlServer if a table has the name 'guest', this table is filtered out while reading the database schema. Such tables are now read successfully.
Schema Read: Composite foreign key constraints can be unordered - If a foreign key constraint is based on a composite key, the relation between source and target columns can be mismatched.
SqlServer CE: NullReferenceException thrown when trying to read the schema for a database that is part of a replication setup - If a SqlServer Compact database is part of a replication setup (used to synchronize data between the server and a 'disconnected' device), trying to create a domain model for such a database resulted in an 'Object reference not set to an instance of an object' exception.
VistaDB: Cannot read schema under Turkish locale - When Turkish locale is set as current locale, the schema read process fails as the ADO driver from VistaDB does a ToUpper internally, giving an exception. VistaDB fixed this issue with VistDB version 4.3.0.27.
Table editor: The rlinq file is not marked as modified after a new table is added. - After making changes to the domain model via the Table Editor, the rlinq file is now marked as modified and a '*' symbol appears in its name. Otherwise the rlinq file could be closed without persisting the changes to the model.
Validation: The DSL model not updated when a primitive member is marked as identity by a validation action - When a domain class does not have an identity, the validation dialog shows an error and it is offering an automatic action for resolving the error. After the user chooses a property to become an Identity, executes the action and closes the validation dialog, the change is now shown in the Visual Designer.
Validation: The validation resolution action for automatic generation of property/field names does not generate unique names. - The resolution actions for automatic generation of property and field names did not take into account whether the suggested name is already used only whether it is a valid identifier. An additional check for the name uniqueness is now performed.
VistaDB: Cannot read schema under Turkish locale - When Turkish locale is set as current locale, the schema read process fails as the ADO driver from VistaDB does a ToUpper internally, giving an exception. VistaDB fixed this issue with VistDB version 4.3.0.27, please use the newest version.
Visual Designer: Inheritance between class and interface which have properties with the same name results in uncompilable code. - Inheritance between class and interface which have properties with the same name resulted in uncompilable code. Explicit implementation of the interface property is generated, but there were public and virtual modifiers which are not valid for this scenario. The fields for both properties had the same name as well.
Visual Designer: Setting IsIdentity to true on an implemented property not reflected on the underlying MetaMember in the metadata model. - Setting IsIdentity=true on an implemented property was not reflected on the underlying MetaMember in the metadata model. The problem was related to the fact that the identity guid from the implemented member was not equal to the identity guid of the meta member. It instead had the identity guid of the actual member in the base class.
Visual Designer: The AUTOINC key generator is not serialized when the class is using Internal identity mechanism. - The key generator was always deserialized as HighLow when Internal Identity was used, given that that is the default. The KeyGenerator is now correctly serialized and deseriliazed.