Data Access 2009.31104

Nov 2, 2009

Telerik OpenAccess ORM Q3 2009 Release Notes (v2009.03.1104)

New Features and Enhancements

  • Metadata API - OpenAccess provides an API to access all metadata information during runtime. This contains the complete database schema definition used. The entry point is at the database instance, you can reach it from the ObjectScope via scope.DataBase.MetaData. To find specific class/table/field/column information you can use Linq.
  • Database level cache API - The OpenAccess database level (or second level) cache needs an API to check the cache content and to evict part of the cache. The API is available at the database instance and can be reached from the ObjectScope via scope.Database.Cache.
  • Configuration support for SNAPSHOT transaction isolation - You can now specify SNAPSHOT in the backend configuration for systems where this is supported (e.g. MSSQL).
  • Shared columns support - A column with a foreign key constraint in the database can be mapped to a simple type field like an integer but it can additionally be mapped to a reference type field like Person.Address. The data in the database is in this case always an integer. The ORM automatically translates the integer to a reference and vice versa. Therefore it is possible to map a single column in the database to two fields in the object model. One of the fields must be of simple type and needs to be of reference type.
  • Performance enhancements for read access - Reading data is complex because lots of metadata and mapping related code has to be executed. The reduction of layers and memory consumption makes the read access faster.
  • SQL Server Compact 3.5 Desktop Edition - OpenAccess can now work with the SQL Server Compact Edition on desktop and server operating systems. Because of the backend limitations in SQL statements like subselects and stored procedures not all OpenAccess functionality is supported.
  • SQL Azure - OpenAccess can now work with the Sql Azure database. The database can be accessed from your local computer or from another machine in the cloud. All OpenAccess functionality including full design time support is provided.
  • .NET connection string support - The definition of the database connection was OpenAccess specific. Now a normal .NET connection string can be used too. The enable project wizard can use and test those strings as well.
  • Full artificial support - After having artificial fields support OpenAccess comes now with artificial types support. This also means that types can be defined on the fly and the database schema can be updated. The access to the artificial types is similar to the artificial fields.
  • API to check and update the database schema - In the development process new versions of the customers product will be shipped. These new versions might contain schema updates as well. OpenAccess offers an API to do this schema changes just before opening the database with a new version. Nevertheless this cannot be an automatic process because schema analysis takes time and schema migration with data migration might be a very long running process.

    Example:
    Database db = Database.Get("DatabaseConnection1"); // do this code before an object scope is obtained
    string ddl = db.GetSchemaAdapter().CreateUpdateDDLScript(null); // using the default properties for checking differences
    if (string.IsNullOrEmpty(ddl) == false) // is there is something to migrate?
    db.GetSchemaAdapter().ExecuteDDLScript(ddl); // migrating the database"
     
  • Auto setting for ObjectScope cache - OpenAccess sometimes had problems keeping references to the data in a fetchplan. This might result in GC runs throwing out the fetched data before the application can access it. The auto reference type setting makes sure that this cannot happen. This is the new default.
  • MySql supports System.Transactions integration - OpenAccess uses the MySql 6.04 driver now. This supports integration into System.Transaction. OpenAccess is able now to use MySql Transaction with it's System.Transactions integration.
  • Use ObjectContainer to copy data between different databases - The object container got a new method to mark all data inside the container as new. This can be used to insert the data into a fresh database. The API is ObjectContainer.MarkContentAsNew()
  • IsDirty(FieldName) missing - Sometimes it is necessary to check if a specific field is dirty. The API was missing and is now added. Breaking change: The enhancer contract has been changed. All enhanced assemblies must be recompiled.
  • Relax the need to call scope.Dispose() - In the past, a call to IObjectScope.Dispose() was required to release the resources of an object scope. The code has been altered so that the GC is better able to collect unused object scopes, relaxing the need to explicitly call Dispose(); it's still a good practice, however.
  • LINQ: Support for Math.Min/Max etc - Allow the usage of System.Math functions Abs/Min/Max/Acos/Asin/Atan/Cos/Sin/Tan/Sqrt/Sign/Cosh/Sinh/Tanh/Atan2/Floor/Ceiling/Truncate/Exp/Log10/Log/Round(a,b)/Pow. The methods will be pushed to the server and so that calculations are possible. Be aware, that different database backends calculate sometimes different values (e.g. Round on MSSQL and Oracle).
  • LINQ: OrderBy clauses not working for calculated expressions - The query 'from p in OrderDetailsExtent orderby p.Number * p.Weight select p' was not working.
  • LINQ: Allow ordering based on methods over columns - Allows the use of some methods like string.ToLower() / string.ToUpper() as an expression for the ordering, e.g. "order by x.Name.ToLower()" .
  • LINQ: Changing ForwardsOnly, ParallelFetch, IgnoreUncommited, Debug and BackendQuery from properties to methods. - The API for OpenAccess LINQ has been changed: The BackendQuery property value is now obtainable from the generates IQueryable instance with the ToString() method.
     
    Example old:
    var q = from c in Scope.Extent() where c.Name == ""Telerik"" select c; Console.WriteLine(q.BackendQuery);
     
    Example new:
    var q = from c in Scope.Extent() where c.Name == ""Telerik"" select c; Console.WriteLine(q.ToString());
     
    The properties ForwardsOnly, ParallelFetch, IgnoreUncommitted have been changed into methods:
     
    Example old:
    var ext = Scope.Extent();
    ext.ForwardsOnly = true;
    ext.ParallelFetch = true;
    ext.Debug = false;
    ext.IgnoreUncommitted = true;
    var result = from c in ext where c.Name == ""Telerik"" select c;
     
    Example new:
    var result = from c in Scope.Extent<Company>().ForwardsOnly(true).ParallelFetch(true).IgnoreUncommitted(true).Debug(false) where c.Name == ""Telerik"" select c;
     
  • LINQ: Move ExtensionMethod Extent() to Telerik.OpenAccess namespace - The extension method Extent() that is the main entry point for creating LINQ queries has been moved out of the Telerik.OpenAccess.Query namespace to the Telerik.OpenAccess namespace so that less namespace using statements are required. This possibly requires customer code changes in cases where only Telerik.OpenAccess.Query was imported; such a file must now only include Telerik.OpenAccess.
  • LINQ: Support for boolean projections - Support for 'where ... select x = y' LINQ statements.
  • LINQ: OrderBy on identity was not working - The query 'from x in PersonExtent orderby x select x' was not working.
  • LINQ: Improve support for non-direct projections - Projecting into a given class
     
    var query = from c in Scope.Extent()
    select new MyPerson
    {
    Name = c.Name,
    Geburtstag = c.Birthday
    };
     
  • Upgrade functionality for enabled projects - The Check Settings wizard should be able to find and fix any discrepancies between the installed version of Telerik OpenAccess ORM and the version used to create the project. This includes all aspects like assembly references, project settings, resources, enhancement and postbuild steps.
  • Reverse mapping should support stored procedures with OUTPUT parameters - Static method to call stored procedures with OUTPUT parameters should retrieve the output parameter values and pass them out via 'out' parameters
  • ora_rowscn pseudo column support for version control - ora_rowscn is a pseudo column in each table in Oracle 10 and above that reports a unique version number for a row. Pseudo columns can be used as backend side version mechanism. The problem was, that OpenAccess delimited the pseudo column together with all other columns. You have to add a long field to your persistent class in order to use this column. Use that for concurrency control with type=backend. 
  • Oracle: Improved reading of NUMBER columns that are mapped to System.Double or System.Single - When a System.Single or System.Double field is mapped for Oracle, the resulting FLOAT (63/126) column can hold values that are bigger than what a System.Decimal can represent. The change affects the way such columns are read as now values exceeding 28 digits can be handled correctly, no longer resulting in exceptions.
  • ObjectContainer performs closure analyzation before serializing - When an ObjectContainer is serialized, it performs a closure traversal before in order to really collect all instances that need to be serialized.
  • ObjectContainer ChangeSet should be version agnostic with regard to OpenAccess API assembly - The serialized Object Container cannot be deserialized if the OpenAccess version has been changed in the meantime.
  • Allow ObjectContainer.Apply() when a transaction on the object container is active - The purpose is to allow modified object containers to fully use the resolve proxy event handler. Otherwise only clean containers can programmatically lazy load instances. ObjectContainer.Apply got a new overload with an additional bool 'force' parameter.
  • Improve handling of ntext database types with ntds driver - NTEXT in sql2000 and OpenAccess produced an exceptions when try to operate with it. Changing to varchar was working.
  • Reverse mapping does not recognize autoinc fields in MySql db tables - When reverse mapping a MySql database, AUTOINC fields are not recognized properly. So IDs of newly inserted objects are not being refreshed after scope.Transaction.Commit(). The reverse mapping wizard has a checkbox now where you can specify per column that it contains a server side calculated value.
  • Two project with the same name in a solution prevents OpenAccess from loading - If a solution contains 2 different projects with the same name OpenAccess addin crashes. It happens because project short names are used in a dictionary instead of unique names. Workaround: Rename one of the projects.
  • Enhancer cannot enhance Linq new types in select - A query like: var result = from o in os.Extent<LINQEntities.Person>() where true select new { o.Age, o.Birthday }; will not be enhanced in the right way.
  • Targets in the Target view in the Check Settings wizard should be sorted alphabetically - In the targets tree view of the Check Settings dialog the classes are also not in alphabetical order. This is non-practical if you have a lot of targets and every time you open the dialog the target you are looking for appears at a different position.


Fixes

  • Stored Procedure generation includes a timestamp column as a parameter while generation INSERT and UPDATE procedures A timestamp column in MS SqlServer can be used for optimistic concurrency. The value is generated by the server and hence it is not required in an INSERT or UPDATE statement. Stored procedures generated for INSERT and UPDATE, for a table that uses timestamp column, include this column in the list of parameters and in the DML statement.
  • ConnectionPool.Return throws null reference exceptions The return of a connection to our pool might throw a null reference exception if the connection produces an error before that was handled by the application.
  • Forward mapping wizard dos not detect nullable datetimes properly - When you try to check the "Set current date time for field on update/create" they are not available for nullable datetimes.
  • Forward Mapping wizard throws a Null pointer exception if the OpenAccess.Runtime assembly is directly referenced in the project - If the OpenAccess.Runtime assembly is referenced in the project the Forward mapping wizard throws a NPE exception and also a message in the error window saying cannot load the HighLowRelationalKeyGenerator.Factory class
  • 'Merge' functionality in the Reverse mapping wizard treats a user marked PK field as a difference against the column on the database - If a view is Reverse mapped and mapped to a class, the user needs to specify the PK manually as the PK cannot be inferred from the database. If the user now performs a 'Merge', this PK field shows as having a difference on the PK setting.
  • Stored procedures are not used for all delete calls - If a table uses a stored procedure for 'delete' operations and there is more than 1 instance to be deleted in a Commit call, the delete procedure is bypassed and dynamic SQL is used instead.
  • GetObjectById gives false results when the FetchPlan is empty. - If you pass a non-valid id value to GetObjectById you do not get an exception but an empty fake object. This is the behavior only in cases where you have done scope.FetchPlan.Clear() before that.
  • Iterating through random access query result not possible when Count was requested before on databases without MARS - When the Count property of a random access query result (e.g. Scope.GetOqlQuery ()) was evaluated before the iteration takes place, the iteration requires a second execution of the query, that was failing on systems without support for multiple active result sets.
  • SqlAnywhere: Support for multiple schemata - SqlAnywhere supports multiple schemata, so does OpenAccess. This is working in the reverse engineering wizard now.
  • ObjectContainer: String representation of a new Object Id is not resolvable - When the identity of a newly added object in an ObjectContainer is converted to a string (Database.OID.ToString(oid)), the resulting string is not resolvable to an OID instance again.
  • The design time cannot handle generic type with more than 2 type parameters - If a generic type has more than 2 type parameters the designtime cannot load such a type and throws a NotSupportedException which ultimately results in class not found exception for this type.
  • LINQ: expression pc.collection.Any(lambdaexpression) gives an exception. - The pc.pccollection.Any(lambda) fails as filter is not pushed correctly to server
  • LINQ: pc.pccollection.Any(lambda) gives exception - The LINQ expression pc.collection.Any(lambdaexpression) gives an exception.
  • LINQ: Aggregates with lambda - Min/Max/Average/Count with lambda expressions fail
  • ObjectView throws null reference exception in master detail scenario. - The grid is calling the IndexOf method of our binding list wrapper. One of the checks there was not completely correct.
  • Dictionaries where key or value type are enums not working, giving InvalidCastException - When a IDictionary field is persisted, an InvalidCastException is thrown. Plain enum fields work however.
  • ObjectProvider.SaveAll does not start a new transaction in error case - The ObjectProvider SaveAll implementation is not error agnostic. If the commit throws an exception no new transaction is started. The new transaction should be started in a finally block.
  • ADS reverse mapping not working - An exception is thrown if you start the reverse mapping wizard against an ADS database.
  • OpenAccessDataSource does not handle byte[] fields correctly - "byte[](binary) fields and persistent references are not handled correctly when checking for optimistic concurrency issues. This is the case when changed concurrency mechanism is used."
  • NTDS driver cannot be used for reverse engineering - On a 64 bit machine with tcp/ip v6 enabled the ntds driver does not work during design time. Test connection during enable project and reverse engineering does not work.
  • Stored procedures with spaces in the name could not be executed - The procedure name is being read only until the first space character. Note this applies only for stored procedures with parameters. SP without parameters and spaces in the name work fine.
  • Schema migration for Firebird fails if a table has a stored procedure that references it - If a table needs to be dropped during schema migration and there are stored procedures that reference this table, the table cannot be dropped unless the procedures are dropped first.
  • SqlAnywhere: Index not found when index columns are read - The update script looks like we want to change the index column to nullable. The wrong schema update situations are detected now.
  • SqlAnywhere: Schema migration might fail when changing field types - When a field type is changed, the resulting column type change might fail on SqlAnywhere because the sp_rename is called instead of ALTER TABLE x RENAME y.
  • After a call to ObjectContainer.CopyTo, PC instances do not track changes correctly - "After a call to ObjectContainer.CopyTo, if changes are made to a PC instance and scope.Commit is called, these changes are not reflected. This applied to only fields from the DFG"
  • A wrong exception is thrown when optimistic verification fails while updating using a stored procedure - If a stored procedure is used to perform an update of a PC instance and the optmistic verification fails, a 'NoSuchObjectException' is thrown instead of an 'OptimisticVerificationException'
  • Autoinc setting is not read for a SQL Server table column if the column has User-defined data type - In SQL Server a database column can have a user defined data type. OpenAccess does not detect the 'Identity' setting for such a column. This can now be specified in the reverse engineering wizard.
  • Forward Mapping: Discriminator value is configurable, not the class id - The mapping dialog shows a wrong label which reads 'Class Id' but it should be 'Discriminator Value'. Both settings can now be done in the forward mapping wizard.
  • Schema update not working if all table names have database prefixes - During schema update we try to read the stored procedures from the default schema in the default database. In case there are no classes mapped without the database prefix an exception is thrown saying that the key was not found.
  • LINQ: Group resolution not working when key is a System.Nullable - When resolving (enumerating the members of) a group, OpenAccess throws an exception in cases where null values are encountered. This can happen frequently with nullable values like DateTime?. The exception message is like 'Non-static method requires a target.'.
  • LINQ: Returned type of a query that calls ONLY select which returns anonymous type is not resolved correctly - "Example: var res = ext.Select(""new(Name as X, Capital as Y)"");"
  • LINQ: Correct handling of string + operator as string concatenation - The plus was not pushed to the server in the right way.
  • Connection validation executed to often - If an command or query produces an error during execution the connection gets the status 'NeedsValidation'. Putting the connection back into the pool executes another query to see if the connection is still valid. The flag was never set back which means that the connection executes an additional query whenever if is given back to the pool.
  • Enhancer: Extension method with generic parameter and generic constraint not enhancable - If the enhanced assembly contains an extension method that extends a generic type and has generic constraints the enhancer throws a null reference exception.
  • DataSource designer not working - The checkboxes in the page designer where the behavior of the DataSource can be defined are not working
  • LINQ: Using String.Length in comparison with parameter (not literal) gives cast exception - When a LINQ expression contains an expression of type 'pc.StringField.Length comparison param' a cast exception is thrown.
  • LINQ Distinct projection not executed on server side, but on client - Using a distinct projection is not done on the server side, but on the client.
  • If using the FetchGroupCollector: Fetch groups with same name must use the Next to point to the fetch group even with the same name - When defining fetch groups which are hierarchically connected to each other and you name the FG of the referenced field with the same name as the one of the master field OpenAccess should automatically know which objects to load. Now it needs the name of the fetch group of the referenced field typed in the 'Next' field even if it is the same name.
  • Views marked as 'Collection' or 'Map' lose this setting when wizard is run again. - When a View is marked as a join table i.e 'Collection' or 'Map' and the settings are saved and the Reverse mapping wizard is invoked again, that view is marked as 'Ignore'. The join table setting is not loaded correctly.
  • The Connection Settings wizard changes the current mapping in the App.config file - When the wizard is closed with "OK" it changes the current mapping in the App.config to "mssqlMapping".
  • Stored Procedure generation fails for a class that contains 2 fields that are mapped to the same column - In a reverse mapping scenario the user can map a column to a reference field. In this case we generate only 1 field - the reference field. The user can manually create the base type field for this column also. In this case the class will have 2 fields that are mapped to the same column. If we try to generate stored procedures for such a class/table, the update stored procedure definition has duplicate parameters defined for the column, 1 for each field.
  • NTDS types not usable - If a query has a projection to a datetime datatype the query returns the backend specific result. For NTDS it is a net.sourceforge.jtds.jdbc.DateTimeHolder which is not visible but an internal type in our NTDS driver we have to make such types visible or map them to the System.DateTime type.
  • Stored Procedure is generated a second time when name is given in the mapping. - When a stored procedure is given in the mapping and a name is set, then the schema update does not detect an already existing stored procedure and tries to overwrite it.
  • C# inner classes cannot be mapped by the forward mapping wizard - If inner classes are marked as persistent the forward mapping dialog writes wrong mapping nodes. This leads to runtime problems. If no mapping has been set everything is working fine.
  • NTDS driver with code page 1250 not working - If the client or server has a code page 1250 set OpenAccess throws and OpenAccess Error: System.ArgumentException: 'Cp1250' is not a supported encoding name. This happens because of wrong translation to the appropriated windows code page name.
  • FxCop reports warning in enhanced cctor - If you run FxCop against an enhanced assembly with persistent classes inside, the enhancer added a field initialization to 0 in the cctor. This is not necessary.
  • Autoinc with oracle not working - If a Oracle trigger is used to set the primary key for new data and ORA1008 is thrown because of a missing parameter.
Have a feature request?

Post your feedback via the Data Access feedback portal or the public forums

What's new across all Telerik products?

See the updates feed

Next Steps

Download for free

Get your fully functional free copy of Data Access.

Get Data Access Sample Kit

Including demos and articles to get you started.

Suggest new features

Help us shape our roadmap.