The ObjectMapper .NET Project

Official blog of the AdFactum ObjectMapper .NET

Archive for August, 2006

New Release – ObjectMapper .NET 1.2.728.0

Posted by Gerhard Stephan on 28th August 2006

This release is a small bug fix for a failure that occures when storing business entities that own multiple links to the same object. The problem was that not all of the link properties have been stored. So this problem has been fixed within this version.

Furthermore I changed a small design issue in the class "Property". The problem was that the property "Name" hide the base property "Name" which normally retrieves the name of the property. Instead of the property name our implementation returned the column name, which leads to some problems if external applications rely on that information. Because of this we changed the name of our property implementation to "ColumnName".

Hope you enjoy the new version.

Cheers
Gerhard

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

Posted in Releases | No Comments »

How to do bind collections

Posted by Gerhard Stephan on 24th August 2006

The ObjectMapper .NET offers different possibilities to map collections to database. All different solutions have pro and contras. This post shall lighten those pros and contras in order to give you the ability to choose the proper solution for your use case.

General IList Binding:

        private IList contacts = new ArrayList();

        public IList Contacts

        {

            get { return contacts; }

            set { contacts = value; }

        }

 

Pro:

  • You can add all objects to the List that are derived from IValueObject.

Contra:

  • You can’t use foreign key constraints.
  • The performance is worse, compared to other solutions, because the List can contain all type of objects. Perhaps the ObjectMapper .NET has to read from multiple tables.

Bound IList Binding:

        private IList contacts = new ArrayList();

 

        [BindPropertyTo(typeof(Contact))]

        public IList Contacts

        {

            get { return contacts; }

            set { contacts = value; }

        }

 

Pro:

  • You get best performance, because the ObjectMapper .NET knows which objects you expect.
  • The ObjectMapper .NET creates foreign key constraints.
  • You get a better data integrity due to the use of foreign key constraints.

Contra:

  • It’s only possible to store objects of the type you specified.

Generic List Binding:

        private List<Contact> contacts = new List<Contact>();

 

        public List<Contact> Contacts

        {

            get { return contacts; }

            set { contacts = value; }

        }

Pro:

  • You get best performance, because the ObjectMapper .NET knows which objects you expect.
  • The ObjectMapper .NET creates foreign key constraints.
  • You get a better data integrity due to the use of foreign key constraints.

Contra:

  • It’s only possible to store objects of the type you specified.

General Generic List Binding:

        private List<Contact> contacts = new List<Contact>();

 

        [GeneralLink]

        public List<Contact> Contacts

        {

            get { return contacts; }

            set { contacts = value; }

        }

Pro:

  • You can add all objects to the List that are derived from the type you specified.

Contra:

  • You can’t use foreign key constraints.
  • The performance is worse, compared to other solutions, because the list can contain all types derived from the type you specified. Perhaps the ObjectMapper .NET has to read from multiple tables.

Important

Using the current version of the ObjectMapper .NET it’s not possible to bind generic IList<T> collections. This is because the generic IList<T> interface does not support the IList interface. We try to offer this feature as soon as possible.

So forget about the following example; it will produce failures:

 

        private IList<Contact> contacts = new List<Contact>();

 

        public IList<Contact> Contacts

        {

            get { return contacts; }

            set { contacts = value; }

        }

 

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

Posted in HowTo | 2 Comments »

New Release – ObjectMapper .NET 1.2.724.0

Posted by Gerhard Stephan on 24th August 2006

Yes – it’s only one day after the last release, but it’s time to release a new version of the ObjectMapper .NET.

The reason are two bugs that occured the last days. The first was a problem regarding the binding of IList collections that leads to a problem when trying to create the DDL file. The other problem was a duplicate key violation when trying to store a tree structure to database.

Both problems have been corrected. As an result of these two bugs, I added the first NUnit tests to the ObjectMapper .NET 2005 project. In further releases this regression tests will be extended in order to get a higher code quality.

Hope you enjoy the new version.

Cheers
Gerhard

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

Posted in Releases | No Comments »

New Release – ObjectMapper .NET 1.2.723.0

Posted by Gerhard Stephan on 23rd August 2006

In this release I fixed a bug that occured when working with BackLinks which have a global join parameter. In some cases the SQL statement for such queries failed because the ObjectMapper .NET missed to add a join constraint.

Furthermore I derived the class AdFactum.Data.Internal.Property from the PropertyDescriptor. This change allows you to access the attributes of a property (e.g. IsRequired, IsUnique etc) and the implementation of the getter / setter delegate (mentioned in the last release note) in order to work with them within your application.

If you want to do that you can derive your own PropertyDescriptor class from the Property class the ObjectMapper .NET uses, or you can access the property descriptors directly by calling the static method Property.GetPropertyInstance (PropertyType).

Hope you enjoy the new version.

Cheers
Gerhard

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

Posted in Releases | No Comments »

A final performance boost

Posted by Gerhard Stephan on 17th August 2006

The following article is obsolete!
The ICreateObject interface is now part of the AdFactum ObjectMapper .NET 1.90.1917 and it’s supported by the new UniversalFactory class. So you don’t have to implement a new factory to get this performance boost.

If you need a final performance boost in your application you have to implement a HashFactory in order to create your entities.

As you might know the ObjectMapper .NET allows you to setup your own factory in order to create the business entities loaded by the ObjectMapper .NET. This circumstance can be used to implement an algorithm that is based on the factory pattern. The creation of a new object using the new method is much more faster than it’s pendant using the Activator object.

Therefore all objects must implement a new interface:

    public interface ICreateObject

    {

        /// <summary>

        /// Returns a new copy of the object type

        /// </summary>

        /// <returns></returns>

        IValueObject CreateNewObject();

    }

This may look like that:

    class Contact : ValueObject, ICreateObject

    {

       

       

 

        public IValueObject CreateNewObject()

        {

            return new Contact();

        }

    }

 

 Now the most exciting part of all. The Factory:

    class HashFactory : IObjectFactory

    {

        /// <summary>

        /// Hashtable that contains the list of template objects

        /// </summary>

        static Dictionary<Type, IFactoryMethod> voHash = new Dictionary<Type, IFactoryMethod>();

       

        /// <summary>

        /// Method to create an object from a type name

        /// </summary>

        /// <param name="typeName"></param>

        /// <returns></returns>

        public object Create(string typeName)

        {

            return Create(Type.GetType(typeName));

        }

 

        /// <summary>

        /// Method to create an object from a type

        /// </summary>

        /// <param name="type"></param>

        /// <returns></returns>

        public object Create(Type type)

        {

            IFactoryMethod voTemplate;

            voHash.TryGetValue(type, out voTemplate);

 

            IValueObject result;

            if (voTemplate == null)

            {

                result = Activator.CreateInstance(type) as IValueObject;

 

                voTemplate = result as ICreateObject;

                if (voTemplate != null)

                {

                    voHash.Add(type, voTemplate);

                    result = voTemplate.CreateNewObject();

                }

            }

            else

                result = voTemplate.CreateNewObject();

           

            return result;

        }

    }

Last but not least, that factory can be used to create the ObjectMapper .NET.

           ObjectMapper mapper = new ObjectMapper(new HashFactory(), persister, Transactions.Manual);

 

And now – boost your application !

Cheers
Gerhard

 

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

Posted in Hint | No Comments »

New Release – ObjectMapper .NET 1.2.716.0

Posted by Gerhard Stephan on 17th August 2006

This release is mainly a performance release.

Using dotNet 2.0 and Visual Studio the ObjectMapper .NET gained about 200% performance compared to the last version. This was possible because I could replace the time-consuming reflection method invocation with a direct delegate call to a dynamic method created at runtime.

The graph shows the differens when loading 10000 objects with about 18 columns.

As a second advantage I added a new feature to the Virtual Links that allows you that the source of a Virtual Link can be also a Virtual Link. Thus enables you to flatten object hierarchies when loading.

          /// <summary>

          /// Division Key

          /// </summary>

          [PropertyName("DIVISION")]

          [PropertyLength(5)]

          public string DivisionKey

          {

              get { return _divisionKey; }

              set { _divisionKey = value; }

          }

          

          /// <summary>

          /// Head of Division Key

          /// </summary>

          [VirtualLink(typeof (Division), "FilterKey", "Key", "DivisionKey")]

          public string HeadOfDivisionKey

          {

              get { return _headOfDivisionKey; }

              set { _headOfDivisionKey = value; }

          }

         

          /// <summary>

          /// Name of the head of Division

          /// </summary>

          [VirtualLink(typeof(Division), "Value", "Key", "HeadOfDivisionKey")]

          public string HeadOfDivisionText

          {

              get { return _headOfDivisionText;  }

              set { _headOfDivisionText = value;  }

          }

 

Hope you enjoy the new version.

Cheers
Gerhard

 

 

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

Posted in Releases | 1 Comment »

New Release – ObjectMapper .NET 1.2.710.0

Posted by Gerhard Stephan on 11th August 2006

As an attentive reader you might have recognized that the minor version of the ObjectMapper changed from 1.1 to 1.2. That happend because of big changes within the new version of ObjectMapper .NET. But step by step.

The biggest change was the remove of the LINK ID used in Link Tables. The origin intention of the LINK ID was that the ordering of the items within a collection should remain untouched. That means after loading an object the items within the child collection should appear in the same ordering like they have been saved. This feature was fine, but almost unused by the developers. It only effected irritated database admins who wondered why the application did not run properly when the delete a link with LINK ID 3 in a collection from 0 to 5. That’s why I kicked it off.

In existing applications that means you have to migrate the content of your link tables and remove the LINK ID. Delete duplicate entries and setup the new primary key.

Example of migration Link Tables in Oracle.

— CREATE BACKUP TABLE
CREATE TABLE LINK_TABLE#COPY AS SELECT * FROM LINK_TABLE;

ALTER TABLE LINK_TABLE DROP PRIMARY KEY DROP INDEX;
ALTER TABLE LINK_TABLE DROP COLUMN LINKID;

— INSERT DATA
TRUNCATE TABLE LINK_TABLE;
INSERT INTO LINK_TABLE(PROPERTY, PARENTOBJECT) SELECT PROPERTY, PARENTOBJECT FROM LINK_TABLE#COPY;
COMMIT;

— DELETE DUPLICATE KEYS
DELETE FROM LINK_TABLE
 
WHERE ROWID IN (SELECT ROWID

                 
FROM (SELECT ROWID,
                               Row_Number
() Over(PARTITION BY Parentobject, Property ORDER BY Parentobject, Property) Num_Dup
                         
FROM LINK_TABLE )

                
WHERE Num_Dup > 1);
COMMIT;

— CREATE PRIMARY KEY
ALTER TABLE LINK_TABLE
 
ADD CONSTRAINT LINK_TABLE_PK  PRIMARY KEY (PARENTOBJECT, PROPERTY);

As an other change I removed the obsolete SmartPointer Pattern completly and added some new constructors that makes it easier to inherit the ObjectMapper .NET.

Furthermore I discovered a problem in our current project that forced me to think about the hierarchy level handling. Imagine you want to setup an email distribution list with a lot of contacts. So you own your distribution object and a collection that contains the contacts of that distribution. Due to the multi client capability (of our imaginated application) we must work with the optimistic locking functionatliy the ObjectMapper .NET offers.  

Now we save the distribution list with all the contacts using hierarchy level 1 in order to save the link between both classes. Meanwhile saving the objects, an other user changes one of the contacts used for the distribution. And BOOM – we get an DirtyObjectException. Why? Because hierarchy level 1 instructs the ObjectMapper .NET to save the object itself and the dependent objects that are direct childs. That’s why we get a dirty object exception, because not only the link but also the object had been saved by the ObjectMapper .NET.

Since the current version the ObjectMapper .NET handles the hierarchy level more sophisticated.

  • 0 means : Used to load or saved flat objects.
  • 1 means : Stores a flat object and only the links to other objects.
  • 2 means : Stores the dependent objects in the 1st level.
  • 3 means : Stores the dependent objects in the 1st level including the links to the objects in the 2nd level.
  • 4 means : Stores the dependent objects in the 2nd level.
  • ….

Because this is hard to remind, I introduced some const values in order to make life more easy.

    public class HierarchyLevel

    {

        public const int FlatObject = 0;

        public const int FlatObjectWithLinks = 1;

        public const int Dependend1stLvl = 2;

        public const int Dependend1stLvlWithLinks = 3;

        public const int Dependend2ndLvl = 4;

        public const int Dependend2ndLvlWithLinks = 5;

        public const int AllDependencies = int.MaxValue;

    }

 

Furthermore I removed some faults that have been found in the last version. The attribute [StaticData] had been inverted. That means that the [StaticData] attribute did not mark the class as static data, but marked it as dynamic. This bug has been fixed now.

As a second thing I removed the overloaded method Equal and GetHashCode. Overloading this methods ended up in some strange failures due to the fact that different objects had been identified as the same because of their identical Id, even if they had been two different object references. This bug has also been fixed.

And last but not least I found the problem that the version attribute did not work as expected under certain circumstances.

Puh. That’s a lot of changes. Hope you enjoy my new version of the ObjectMapper .NET

Cheers
Gerhard

 

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

Posted in Releases | 1 Comment »

How to setup database tables instantly

Posted by Gerhard Stephan on 9th August 2006

If you think on NUnit testing it is mandatory to ensure that your starting position is always the same. Especially when working with data that changes during a test run.

One solution for writing NUnit test is to setup new database tables before running the tests. Using the ObjectMapper .NET this can be done with a few lines.

            SqlPersister persister = new SqlPersister();

            ObjectMapper mapper = new ObjectMapper(…);

           

            /*

             * Add the types

             */

            ArrayList types = new ArrayList();

            types.Add(typeof (Contact));

            types.Add(typeof (Company));

           

            /*

             * Create the tables instantly

             */

            StreamWriter writer = new StreamWriter(new MemoryStream());

            persister.WriteSchemaDif(writer, types, mapper);

            writer.BaseStream.Seek(0, SeekOrigin.Begin);

 

            SqlFile file = new SqlFile(writer.BaseStream);

            file.ExecuteScript(persister);

 

The hint is to export the tables to a memory stream and to use this stream for executing the SqlFile.

Cheers
Gerhard

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

Posted in HowTo | No Comments »

Attribute: [StaticData]

Posted by Gerhard Stephan on 7th August 2006

Using the StaticData attribute you can tell the ObjectMapper .NET that it’s your intentation that the class only contains static data.

What changes if the ObjectMapper .NET knows that this class shall only contain static data? If you’re calling the DeleteRecursive method, the child objects won’t be deleted, because the class is marked as Static.

So the attribute prevents the deletion of objects that contains static data.

Here’s the example code:

    [Table("PRICES")]

    [StaticData]

    class Price : ValueObject

 

 

 

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

Posted in Attributes | No Comments »

New Release – ObjectMapper .NET 1.1.702.1

Posted by Gerhard Stephan on 2nd August 2006

I’m proud to present the new version of the ObjectMapper .NET.

First of all, it’s linked against the new release of the Oracle ODP.NET Driver. The driver can be downloaded from http://download.oracle.com/otn/other/ole-oo4o/ODAC10202.exe. Using the ODP .NET beta driver with the new ObjectMapper .NET will lead to an error.

As the second big change I renamend the attribute [BindCollectionTo] to [BindPropertyTo]. I changed the name because the new property is more general. Now you can bind a collection and (that is new) a interface type to a special target class.

            [BindPropertyTo(typeof (Contact))]

            public ContactCollection Contacts

            {

                  get { return _contacts; }

                  set { _contacts = value; }

            }

 

                        /// New functionality

 

            [BindPropertyTo(typeof (Contact))]

            public IContact Contact

            {

                  get { return _contact; }

                  set { _contact = value; }

            }

 

This new feature enables a better integration of the Persistent Domain Object Pattern, because it does not require to have two properties – one for the UI and one for the database mapping.

Furthermore I removed a bug of the method "RemoveFromCollection". If the item to remove has not been found within the collection, the ObjectMapper .NET always removed the last item. And I removed a bug that occured when the ObjectMapper .NET had to solve more than one VirtualLink that linked to the same target class.

Additionaly I added thread safety for the cache of the ObjectMapper .NET. I did not ever had any problems with it, but you’ll never know.

And last but not least, the ObjectMapper .NET is not marked as sealed anymore. Thus enables you to inherit the ObjectMapper .NET in order to build your own default constructor.

Cheers
Gerhard

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

Posted in Releases | No Comments »