FastObjects .Net brings object-oriented database technology to the .Net environment. Given that the majority of .Net database applications employ RDBMSes on their back end, you might wonder if it makes sense to choose an OODBMS (object-oriented database management system) instead.
It is a logical choice. Put simply, object relationships are already described in the class hierarchy, so wouldn't it be nice if those relationships were preserved when objects are written to or recalled from persistent storage? FastObjects .Net makes it happen.
The invisible hand
FastObjects .Net runs in what is referred to as local mode, wherein FastObjects applications open database files directly.
This is the preferred mode for developing a FastObjects application because no server is required; deployed applications communicate via TCP/IP to a FastObjects app server, which is written in native code. So, while apps using FastObjects .Net are limited to the .Net platform, the FastObjects server can run on Linux, Windows, or Solaris.
FastObjects .Net development components plug themselves into Visual Studio .Net. Installation adds a FastObjects menu, from which you can enable a project, attaching the necessary source files and assembly references to your FastObjects-based projects.
In addition, FastObjects projects get new toolbox controls for quickly accessing FastObjects .Net wrapper objects. These objects hide the details of binding a data control, such as a DataGrid, to a FastObjects database back end. Hiding those details make it easier to create database apps, because you don't have to deal with the little -- but complicated -- stuff.
FastObjects implements transparent persistence: Once an object is in the database (persistent), any changes an application makes to the object are automatically written to the database. Because the app need not explicitly call a store method, it substantially reduces the amount of database code you must write, compared to an RDBMS.
FastObjects works this powerful magic by altering the IL (Intermediate Language) code in a post-compilation step called "enhancement." Inside the new FastObjects section of the project properties table, you'll find a Boolean property for "enhancing" the project. Setting this Boolean to true activates the FastObjects enhancer. Whenever the object is compiled, the enhancer adds instructions to the IL code that implement the automatic database management.
Before this sorcery is effective, however, you have to make an object persistent. This requires a smidgen of declarative and imperative code. The declarative code consists of the "Persistent" attribute, with which you ornament any class of objects you want to make "persistent-capable." The imperative code involves opening the database; obtaining a session object, also known as the object scope; then calling the object scope's Add() method -- passing the object to be persisted as the single argument.
The rest of the database-access process is handled by invisible FastObjects code that the enhancer snuck into your assemblies. Fetch a persistent object either by retrieving it from the result set of a query or by accessing its contents by following a reference in any other persistent object. Modify a persistent object's contents, and that invisible code automatically writes the updated copy back to the database.
Admittedly, it's not quite that simple. All operations on a database must take place within a transaction scope: Open a transaction with a call to the Transaction class' begin() method, and subsequent alterations to persistent objects are written when the transaction is closed with a call to commit(). If something goes amiss, calling rollback() throws away any alterations, and returns the database to its state prior to begin().
To maintain database integrity, changes are first recorded to a log file; if a system crash occurs, database updates can be quickly restored. Plus, all objects are written into persistent storage with associated checksums to safeguard against data corruption.
Within the database, objects of a given class are held within an abstract container called an extent. An extent is one means of reading objects from the database. FastObjects supports the OQL (Object Query Language), and extents can be referenced in OQL queries as well as C#. A query string can be placed into a query object, executed on the database, and the results iterated through as necessary.
The easiest way to retrieve an object from the database is to simply reference one of its elements. Suppose persistent object A references persistent object B; fetch object A from the database, then access object B via the referencing field in object A. FastObjects will automatically instantiate object B and retrieve its contents from the database. From the programmer's perspective, it appears that object B has been in memory all along -- exactly what you want.
FastObjects .Net installs smoothly, painlessly insinuating itself in your .Net development process. Attaching a FastObject database to your ASP.Net applications is simplified by the wrapper objects added to the toolbox, and there's plenty of guidance in the online examples.
FastObjects .Net also ships with a database administration tool and the Developer Tool. The latter is an extremely useful window into any FastObjects database, allowing you to navigate through the class hierarchy trees within the database dictionary, explore objects in the database, and even test-fire OQL queries. I was initially concerned that the enhancement process might interfere with debugging, but I had no problems debugging FastObjects programs during testing.
Users of Poet and preceding FastObjects editions will get the most benefit from this .Net version. The OODBMS is fast and easy to use, because much of the detail work is done in the background or automatically. If you've got a .Net database app and that RDBMS isn't doing the job, do yourself a favor and try out FastObjects .Net.