Sunday, May 29, 2005

Relaxing, again!



This is still on our party! I'm sorry that I have no picture where you can see me with my friends. But I did not get all pictures until now...

The patent shock!

Today I'm going from one shock to another... (but not only today).

Microsoft got the patent for ORM. How is this possible. There are solutions out there doing exactly what the patent describes. They are out there for years now!

The patent is silly. Why are people not looking before they give a patent to someone!

The Longhorn shock!

Longhorn is turning more and more into a shock! First it seemed to be a cool new operating system with a lot innovations. Then they removed WinFS. After that they ported back Avalon and Indigo (which is not bad) but somehow made Longhorn no longer unique.

The newest rumour is that they are removing also the Longhorn fundamentals: see Microsoft Watch.

Hopefully at least something stays!

[Opf3] What is the AutoNumber property in the FieldAttribute

The "AutoNumber" property in the FieldAttribute may be set to true to have Opf3 retrieved the next number for a primary key from the storage (database etc). This works only with databases that support sequences (like Oracle, PostgreSql, PervasiveSql) or autoincrement (like Access, MSSQL Server, VistaDB).

All storages that come with the framework support this feature. It's highly recommended that all storages that are released to the public support it.

AutoNumbers are supported only for one property of the persistent object! Opf3 does not throw an exception if you mark more then one property as "AutoNumber" but will only fill the first that is found.

[Opf3] Delete objects that are part of a loaded ObjectSet

How to delete objects that are part of a loaded ObjectSet<T>? The ObjectSet contains a list that is called the "RemovedList" (there is a property that is also named like that).

All objects that are removed from the ObjectSet by using the RemoveAt, Remove, RemoveAll methods are moved to the RemovedList. When the ObjectSet is saved all items on the RemovedList are deleted.


ObjectSet<User> os = context.GetObjectSet<User>("UserName like {0}", "Jason%");

// Remove the first object from the ObjectSet.
// The object is moved to the RemovedList.
os.RemoveAt(0);
// Returns exactly that item.
User user = os.RemovedList[0];

// Saves all changes to the objects and deletes
// the objects in the RemovedList.
context.PersistChanges(os);


How to remove an item from the ObjectSet without deleting it. You have to move it to the RemovedList and remove then from there. It's a little bit complicated but not required very often.


// Move the first item to the RemovedList.
os.RemoveAt(0);
// Remove it from there. The item is now no longer
// saved nor deleted.
os.RemovedList.RemoveAt(0);

Relaxing

Sometimes everybody needs to relax!



We had a little party in our garden where we drank a little bit beer and grilled some meat and vegetables. It was really funny because we came all together and I met people I have never seen or not seen for a long time.

This is actually the garden of my dormitory (at vienna).

Wednesday, May 25, 2005

Article about testing published

In the current issue of the "DotNetPro" has been released my article on unit testing with Whidbey. The current issue (06/05) is found here (german).

Friday, May 20, 2005

[Opf3] ICustomPersister: What a strange interface?!

What is ICustomPersister? First: it's an interface. Second: it allows to create complex objects which hold a bunch of persistent objects.

Perhaps you think now: WHAT?

ICustomPersister contains two methods: Load, Persist. An object that implements this interface can manage the load and persist process by itself. When an object implementing this interface is persistet using the ObjectContext:

context.PersistChanges(objectImplementingICustomPersister);

The ObjectContext returns the control to the object. The object can now save it's parts by using the ObjectContext. The same happens while loading the object.

When is something like this useful?
Immagine you have a complex object. For example a list of objects (the ObjectSet<T> implements this interface) or a car object. The car, for example, has two doors and an engine. It holds internally those three objects and knows how to save or load them from the database. When you load the Car object from the storage you have simply to set an instance of the Car object as argument of the GetObject method of the ObjectContext.

Car car = context.GetObject<Car>(new Car(), "Name = {0}", "Bugatti");

The ObjectContext returns the control of the load process to the instance of the Car object. The Car object gets the query and the instance of the ObjectContext that redirected the control. This allows the object to load the parts by itself.

While saving:

context.PersistChanges(car);

the object has also full control over its persisting behaviour. The car object can save first the doors and then the engine or first the engine and then the doors. The ObjectSet<T> saves for example all persistent objects in the main list and deletes all persistent objects that are found in the RemovedList property of the ObjectSet<T>.

Something is wrong with my harddisk

I do often backups. :) But it's waste of time. Yesterday I got for 10 minutes "UNMOUNTABLE_BOOT_VOLUME" while booting Windows XP. I was desperate. After having given the computer a little bit free time it worked again.

When I'm back at vienna, I'm going to buy a new harddisk and more RAM. Whidbey eats a lot.

[Opf3] "Own" the persistent object

Opf3 offers a few features to "own" a persistent object. Those features are interfaces that have to be implemented by the persistent object.

The first interface (and also the most important) is: IObjectNotification. This interface contains methods that are invoked before an action is going to happen and after the action has happened. This interface allows you to modify the object or build some verification code into your persistent object that is invoked before or after an action. The actions supported are:
  1. Delete,
  2. Insert,
  3. Update,
  4. Populate (before and after the object is populated with data) and
  5. MarkDeletion (before and after an object is marked to be deleted).

Another interface, that allows specify how an object is populated, is the IPopulateHelper interface. This interface allows the persistent object to populate itself. It's easy to implement it and you get for each column of the table the name and the data. It's then up to the object to populate itself.

Thursday, May 19, 2005

[Opf3] New version of Opf3 released

We released a new version of Opf3 today. This version contains a lot improvements and fixes. A list can be found here. Check out www.opf3.com for additional information about the new version.

Opf3 supports now also PostgreSQL and PervasiveSQL. The PervasiveSQL is still alpha because of some problems with the underlying Pervasive .NET Adapter.

Monday, May 16, 2005

[Opf3] Using multiple storages and web services

I got the following question sent today. I was thinking that this could interest also other people:


Is it possible using Opf3 to do the following scenario.

On a web server
Retrieve data from SQL server and send data to client via web service.
On the client
Persist the data retrieved from the server to say VistaDB db, with a few more fields added?


Answer:

Yes, it is possible. You can load data from one storage and persist it to another storage. The following post shows how to do that:
http://christianliensberger.blogspot.com/2005/05/opf3-using-multiple-storages.html.

You have only to think about a few more things since you are sending the object via a web service. It is recommended to implement the ISelfContainingObject when remoting an object or loading an object and then persisting it with another instance of the ObjectContext. This has to be done because without implementing the interface an object is coupled to the instance of the ObjectContext that is used to load it. The ObjectContext manages internally the status of the object (has the object been loaded, deleted etc.). This works fine when you are using one instance of the ObjectContext within your application or you are loading all objects with the same instance of the ObjectContext that is used to save the changes.

When you implement the ISelfContainingObject interface the object itself manages the status and holds its concurrency data. This scenario works fine when you use different instances of the ObjectContext which are bound to the same database (storage) or remote the object and save it in the end by using an instance of the ObjectContext that uses the same database as the one that loaded it.

In your case you have two different databases. When you implement this interface (ISelfContainingObject) you have to reset the status of the object manually. This is done by the following piece of code:


// Reset the state of the object.
((ISelfContainingObject)obj).ObjectInfo.ObjectState = ObjectStates.None;


Now Opf3 thinks that the object hasn’t been loaded from any storage and you can safely store it (Opf3 does an insert). When you are not implementing the ISelfContainingObject interface you have no problems in this specific scenario. The ObjectContext (you used to load the object) holds internally the status of the object and the other instance does not care about that status and treats the object as if it would be a new one (= insert to the storage).

But you have problems when you load an object, remote it using remoting or web services and try to save it to an instance of the ObjectContext that is bound to the same database that you used to load the object from. Without implementing the ISelfContaining interface once the object left the current AppDomain the ObjectContext removes the status and concurrency data. The ObjectContext “thinks” that the object has been destroyed (he can’t reach it anymore). When the object returns to the AppDomain and is also saved with the same instance of the ObjectContext (used to load it) the status data can’t be found anymore (= insert to the storage).

For your scenario I would recommend implementing the ISelfContainingObject interface and reset the ObjectState. It’s a clean way and you have no problems afterwards when using the persistent object in your application. If you use the persistent object only to do a copy from the old database (or for doing an import) you don’t need to implement the interface as long as you don’t remote the objects afterwards and you save the objects always with the same instance of the ObjectContext you used also to load them.

Sunday, May 15, 2005

Microsoft Research: Singularity

Yesterday I run over a cool OS done by the guys at Microsoft Research. It is called "Singularity" and written in C# (99% of it).

More about it is found here: http://research.microsoft.com/os/singularity.

A video where Jim Laurus and Galen Hunt explain their research OS is found at channel 9: http://channel9.msdn.com/ShowPost.aspx?PostID=68302

I have the flu

I'm not feeling well. Headache and my bones hurt. Hopefully this flu gets over soon :)

[Opf3] Transactions

The framework supports also transactions, if the underlying storage does. The following example shows how to use transactions in Opf3:


ObjectContext context = new ObjectContext(new AccessStorage(@"C:\", "northwind.mdb"));

context.StartTransaction();
try
{
    // Load or save objects to the storage.
    // Commit the transaction.
    context.Commit();
}
catch (Exception ex)
{
    // Roll the transaction back.
    context.Rollback();
    // Do something else.
}


It's recommended to use the ObjectContext's methods to start, rollback or commit the transactions. If the storage does not support transactions those calls are ignored.

[Opf3] Using multiple storages

Opf3 allows you to use multiple storages and multiple contexts in one thread of your application. The following sample shows the usage of two instances of the ObjectContext class to copy data from one storage to another.


ObjectContext context1 = new ObjectContext(new AccessStorage(" connectionstring "));
ObjectContext context2 = new ObjectContext(new MsSql2000Storage(" connectionstring "));

ObjectReader<User> or = context1.getObjectReader<User>();
foreach(User user in or)
{
    context2.PersistChanges(user);
}


The sample loads all user objects from the first storage by using an ObjectReader. An ObjectReader is similar to the IDataReader of the .NET framework. The class represents a storage forward-only cursor that allows to go through all objects in the storage and process them somehow.

Saturday, May 14, 2005

[Opf3] Set up the framework

Since everything needs to start somehow, also Opf3 needs to be initialized. Some ORM make it really hard to set them up. For Opf3 we tried to make this as easy and short possible. The following lines set up the framework (which includes also an instance of the Md5ConcurrencyManager to manage simultaneous access to the storage).


ObjectContext context = new ObjectContext(new AccessStorage(@"C:\", "northwind.mdb"));
context.ConcurrencyManager = new Md5ConcurrencyManager();


The code creates an instance of the ObjectContext. The ObjectContext is the main class in Opf3. It allows you to load objects from storage and store them back there.

The framework is now fully set up!

The following line loads an User object from the storage (the database):


User user = context.GetObject<User>("UserName = {0}", "Some guy's name");


This sample specifies also a name of the user that is loaded. The name is "Some guy's name". Opf3 supports IDbParameter by using the syntax of string.Format, which means {0} for the first parameter, {1} for the second, etc... For more information about the User object look here.

[Opf3] Introduction for Opf3 posts

This should be a short introduction to the most important terms of the Opf3 framework:

  1. Opf3 runs on .NET 2.0 and above. It does not run on .NET 1.0 or 1.1 because it uses generics and Nullable types that are only found in .NET 2.0 (and above).
  2. Storage is a physical storage for data. A database is a storage. An xml file can also be a storage. You could also create a storage that persists data or loads data from any device or file that is imaginable.
  3. Persistent object is an object that can be loaded from the storage and saved (persisted) to the storage. A persistent object is mapped to a table in the storage (or for example a node in xml). Each row in that table represents one instance of a persistent object. The fields (in that table) are mapped to the properties of the persistent object. The mapping is defined in the peristent object class itself. By using .NET attributes.
  4. A ConcurrencyManager is a class that manages concurrent access to the storage (it implements a special interface, which is part of Opf3).
  5. ... more is introduced with the posts on Opf3 or found also here.

Welcome

Hi,

Let me introduce myself: I'm Christian Liensberger, one of the main developers of an Object Relational Mapper (ORM), student and author for a german .NET magazine (called DotNetPro).

The ORM we are developing is called Opf3 (for Object Persistent Framework 3.0). I'm going to post some examples and tweaks for that framework in this blog. I want also post information about the development process of Opf3 (future features, releases, ideas etc.)

But, this blog will also have to do with my personal life (also my adventures as student). Sometimes I will also post here my feelings or ideas on other stuff then only .NET or any other computer related topics.

Enjoy!