The ObjectMapper .NET Project

Official blog of the AdFactum ObjectMapper .NET

Archive for May, 2006

Tutorial 2: Setting up the database, store and query some data

Posted by Gerhard Stephan on 31st May 2006

This tutorial shows how to execute an SQL file in order to create the tables. Furthermore it shows a simple example how the query API works and how to store data. But first things first.

In Tutorial 2 I decided to use NUnit instead of a console application. The advantage of NUnit is, that we can build different test cases in order to show different aspects of the ObjectMapper .NET. So If you load the Tutorial 2 you have to setup NUnit correctly in order to run the examples.

Project Configuration

Before we can insert data, it’s necessary to create a new database. In the tutorial we are going to create a new Microsoft Access Database by copying an empty database and than executing the DDL file.

            public void CreateAccessDatabase()

            {

                  /*

                   * Copy the template database as the new database

                   */

                  File.Copy(@"..\..\emptyAccessDb.mdb", "accessDb.mdb", true);

 

                  /*

                   * Create the schema

                   */

                  new ExportSchema().ExportAccessDDL();

 

                  /*

                   * Open the access db and execute the created script file

                   */

                  AccessPersister persister = GetAccessPersister();

                  SqlFile file = new SqlFile("Marketplace.access.sql");

                  file.ExecuteScript(persister);

                  file.Dispose();

                  persister.Dispose();

            }

 Now we created a working database – with all relations a database must have.

Tutorial02 - E/R Model

In our example we want to add a new user to the database. Looking at the source code of the User entity you see that the "Logon" property is defined as unique. So we have to care for duplicate values when storing new users.

            /// <summary>

            /// Gets or sets the logon.

            /// </summary>

            /// <value>The logon.</value>

            [PropertyLength(32)]

            [Required]

            [Unique]

            public string Logon

            {

                  get { return logon; }

                  set { logon = value; }

            }

In order to prevent a sql exception because of duplicated logon values, we have to check if a logon already exists and then to cancel the save operation. Furthermore this has only to be checked if we want to add new users to database. Existing Users don’t need to be checked, because they are only getting updated.

As you can see within the following code, every entity has a field named IsNew which is set by the ObjectMapper .NET. This field defines if a entity has already been stored to database. Our first query condition is a check to the Logon property of the User entity. So we are going to count all users with the specified logon column. If the count is greater than 0, there has already been stored a user entity to database.  

            /// <summary>

            /// Creates the user.

            /// </summary>

            /// <param name="mapper">The mapper.</param>

            /// <param name="user">The user.</param>

            /// <returns>True, if the user could be stored</returns>

            private bool StoreUser (ObjectMapper mapper, User user)

            {

                  /*

                   * If the user is new, check if the logon name does already exists

                   * If the logon name does exist, return false

                   */

                  if (user.IsNew)

                  {

                        ICondition logonCondition = new AndCondition(

                             typeof(User),    

                             "Logon",

                              QueryOperator.Like_NoCaseSensitive,

                             user.Logon);

                       

                        int count = mapper.Count(typeof(User), logonCondition);

                        if (count > 0)

                             return false;

                  }

 

                  /*

                   * if the logon name is not used or it is an existing user, than store the user

                   */

                  mapper.Save(user);

 

                  return true;

            }

The outcoming SQL looks like :

SELECT COUNT([USERS].[ID]) FROM [USERS] WHERE UCASE(TRIM([USERS].[LOGON])) like UCASE(TRIM(?))
 
INSERT INTO [USERS] ([ID],[NAME], [MD5PASSWORDKEY], [LOGON]) VALUES (?,?,?,?)
 

This statements have been created for Microsoft Access. If you are using an other database persister like Oracle, this SQL statements will change.

The whole tutorial can be download from here:
Tutorial 2: Setting up the database, store and query some data

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading...

Posted in Tutorial | No Comments »

New Release – ObjectMapper .NET 1.0.430.0

Posted by Gerhard Stephan on 30th May 2006

Developement goes on – and bugs will be fixed. Even if I released the first release version yesterday …

In this release I fixed some bugs which I found while developing the second tutorial for the ObjectMapper .NET.

  1. The Access Database TSQL Uppercase method is called UCASE – not like implemented UPPER.
  2. The Tables within the FROM clause of an SQL Statement for Access Databases will now be quoted. That is because Queries like ‘SELECT * FROM USER’ failed, because USER has been a reserved word for Microsoft Access. This bug has been also fixed with this release.

Furthermore I changed the methods BeginTransaction, Commit and Rollback so that they can be overridden. In special cases this might be useful if you want to execute special methods before committing data.

And I implemented one of the most user friendly extensions. Nested collections and dictionaries don’t have to be instantiated anymore. If a collection or dictionary is NULL it will be treated like an empty collection.

So it’s worth to download the new release
Cheers

Gerhard

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading...

Posted in Releases | No Comments »

New Release – ObjectMapper .NET 1.0.424.0

Posted by Gerhard Stephan on 29th May 2006

Today I’m proud to present the first release version 1.0 of the ObjectMapper .NET.

It’s now 3 years ago that I started to develop the ObjectMapper .NET. So it took me a long time to get the ObjectMapper .NET to that what it is today – a powerful object relational mapping tool for .NET.

And I think the story has just begun.

Hoping to get a big community, I want to make some advertisements and give interviews in .NET magazines within the near future. I would be glad If you all could help to make the ObjectMapper .NET a well-established tool within the .NET developer community.

The current release brought some new minor features like the capability to store TimeSpan fields directly to database. Furthermore the numeration of unique and foreign keys are not global anymore. That makes it easier to handle the unique and foreign keys when doing migration stuff.

For the future I plan to support the MySQL database and what is most importent to me the SQL Server Mobile Edition. As I know the ObjectMapper .NET would than be the first object relational mapping tool that supports the SQL Server Mobile Edition.

And sure I hope to get suggestions from you as a developer to improve the ObjectMapper .NET.

So have a successful time
Cheers

Gerhard

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading...

Posted in Releases | No Comments »

New Release – ObjectMapper .NET 0.99.422.0

Posted by Gerhard Stephan on 22nd May 2006

This release is almost a beta release of version 1.00 for the ObjectMapper .NET. Primarly I did some performance enhancements that comprises the commit of value objects to the database.

Furthermore I splittet the class MapperException to single Exceptions for every use case. Therefore I implemented a MapperBaseException which acts as the base class for all derived exceptions. That makes it more easy to catch diferent exception types.

Additionaliy I added some new constructors which supports the versioning of the data model and last but not least, I fixed a bug in the method SetNestedObject which let the ObjectMapper .NET crahes when using this method in a Microsoft Access enviornment.

So all in all I hope to name the next release as version 1.0.

Cheers
Gerhard

 

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading...

Posted in Releases | 2 Comments »

New Release – ObjectMapper .NET 0.99.417.0

Posted by Gerhard Stephan on 17th May 2006

Storing object trees that contains self referencing objects turned out as a bigger problem as expected.

We found out that it’s not always sufficient to generate one insert per object. Sometimes it’s necessary to update the object reference separately after doing the insert. That is the case if I have a tree structure like this:

///<summary>
/// Company Object
///</summary>
public class Company : ValueObject
{
      private string name;
      private Company parent;
      private ArrayList childs = new ArrayList();
 
      public string Name
      {
            get { return name; }
            set { name = value; }
      }
 
      public Company Parent
      {
            get { return parent; }
            set { parent = value; }
      }
 
      [BindCollectionTo(typeof(Company))]
      public ArrayList Childs
      {
            get { return childs; }
            set { childs = value; }
      }
}
 
 

Company c1 = new Company();
c1.Name = "Parent";
 
Company c2 = new Company();
c2.Name = "Child";
 
c2.Parent = c1;
c1.Childs.Add(c2);
 
AccessPersister persister = new AccessPersister("test.mdb");
ObjectMapper mapper = new ObjectMapper(new DefaultFactory(), persister);
 
mapper.Save(c1);
 
mapper.Dispose();

The property named "Parent" of the child object can only be set, if the parent object has already been inserted into the database. That’s why the ObjectMapper .NET code had to be changed in order to do the insert of the child and parent object. After that insertion, the ObjectMapper .NET updates the parent property using a separate update SQL statement. In older releases the code produced an exception or did not store the tree correctly in database.

To cut a long story short the code mentioned above does work in the current release.

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading...

Posted in Releases | No Comments »

Tutorial 1: How to create a DDL file out of your business entities

Posted by Gerhard Stephan on 15th May 2006

The first ObjectMapper .NET tutorial shows how to create a valid DDL file out of your business entities.

First we will need some business entities. In terminology of the ObjectMapper .NET, Business Entities are called "ValueObjects". That is because they will only contain the raw values.

Marketplace class diagram

In the first draw we will have an user class, his marketplace items and the bids. Our szenario: A user wants to sell marketplace items to an other user which can place bids on the items.

To export the entities we have to add the entity types to an ArrayList(). 

///<summary>
/// Gets the business entity types.
///</summary>
///<value>The business entity types.</value>
private ArrayList BusinessEntityTypes
{
      get
      {
            ArrayList result = new ArrayList();
            result.Add(typeof(User));
            result.Add(typeof(MarketplaceItem));
            result.Add(typeof(Bid));
                 
            return result;
      }
}
Than the DDL file can be exported by the ObjectMapper .NET and the WriteSchema method.
 
///<summary>
/// Exports the access DDL.
///</summary>
private void ExportAccessDDL()
{
      IPersister accessPersister = new AccessPersister();
      ObjectMapper mapper = CreateMapper(accessPersister);
      mapper.WriteSchema("Marketplace.access.sql", BusinessEntityTypes);
      mapper.Dispose();
 
      ShowFile("Marketplace.access.sql");
}
 
But that’s not only possible for a Microsoft Access database. It’s also possible for Oracle, Microsoft SQL Server and XML Schema files.
The demo can be downloaded using the following link:
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading...

Posted in Tutorial | 1 Comment »

New Release – ObjectMapper .NET 0.99.415.0

Posted by Gerhard Stephan on 15th May 2006

Today I collegue of mine and I found at the same time a bug in the ObjectMapper .NET. The mapper failed to store objects that contains references to the object itself (so called circular references).

I really was surprised that such a bug did not occur earlier. But O.k. I fixed it by adding a hashtable to the save routine that checks if the value has already been stored to database.

So everything should be fine now.
Wish you a great day.

Gerhard

1 Star2 Stars3 Stars4 Stars5 Stars (1 votes, average: 4.00 out of 5)
Loading...

Posted in Releases | No Comments »

New Release – ObjectMapper .NET 0.99.411.0

Posted by Gerhard Stephan on 11th May 2006

This release is primary a bug fix for Microsoft SQL Server and Access Database Persister. Querying an aggregated ValueObject ended up in an exception thrown by the persister. The problem was that the Id has not been used to query the table – the persister did use the object itself to build the query. Needless to say that this wasn't quite a good idea, because the persister used the object reference to query a GUID column in database.

But now everything should be fine again.

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading...

Posted in Releases | 1 Comment »

New Release – ObjectMapper .NET 0.99.408.0

Posted by Gerhard Stephan on 8th May 2006

Today I released the a new ObjectMapper Version which contains some bug fixes and one primary change – the loss of the software driven referential integrity check that the ObjectMapper .NET supports in prior versions. I think this point is worth to explain in detail.

The software driven referential integrity check has been marked as obsolete because it's a fault-prone process.
In prior versions of the ObjectMapper .NET the developer could choose a SmartPointer algorithm to ensure the referential integrity of the database. As the on-road test shows this is not a very secure alternative to check the referential integrity by a software algorithm. Why? It's because system crashes can produce an invalid state of the link counter. Furthermore it costs a lot of read and write operations to update all link counters. Last but not least it can't be used in a environment that allows multiple instances of the ObjectMapper .NET, because every instance of the ObjectMapper .NET would change the smart pointers of the other instance. I think there might be many other reasons more. That's why I set the Constructor to Obsolete. In the next version of the ObjectMapper .NET I'm going to remove the constructor completely.

The BackLink attribute can now be used with a GlobalParameter in order to specify the parent object.
The purpose of a backlink is to link data from the parent object into a child object. One problem appears if a child object is used by different parents. If you make a count on the child object you will get for instance 1 value, but if you load the child objects with a selection you will get 2 objects. Why? It's because the child is referenced by 2 parents and therefore will be loaded 2 times. That's the correct behavior, but not always the wanted behavior. That's why I added the possibility to add a GlobalParameter to the BackLink Attribute in order to specify the parent object which shall be referenced when loading the child. It's implemented like the GlobalParameter used by the VirtualLink Attribute.

Bug Fix: WriteSchema on OracleRepositoryPersister
The OracleRepositoryPersister did not evaluate the tablespace which have been stored in the repository database when writing the difference scripts. The ObjectMapper .NET always took the default tablespace 'USERS' instead of the correct one. This bug has been fixed now.

Bug Fix: Create and use new identifiers for virtual links in order to allow multiple aggregates of the same class.
The prior release of the ObjectMapper .NET had the problem that a class could only contain one aggregate to another object that has been embedded by using VirtualLinks. Imagine you have a order info object which contains a customer address and a shipping address. So you have two address objects as an aggregate within the order info object. So far so good. Now image you want to add two virtual links to the order info object which links the address data from both address aggregates into the order info object. Boom – older versions of the ObjectMapper .NET did not deliver the correct result. This bug has been fixed now.

That have been the changes in the current release.
I hope you enjoy the ObjectMapper .NET.

Cheers
Gerhard

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading...

Posted in Releases | 1 Comment »