ierDeveloper is an Object-to-Relational (O/R) mapping tool that integrates with Visual Studio versions 2002 and higher. TierDeveloper maps Relational Database Management System (RDBMS) tables to .NET objects (VB.NET and C#), so that a programmer needs only to “get” and “set” an object’s properties to retrieve or store it, without needing to know that it’s underpinned by a database at all.
O/R mapping is something of a half-way house between relational and object databases. On the one hand, it’s able to leverage many of the benefits of a “pure” object database, like strongly typed objects and transparent persistence, meaning that developers can navigate and update the database without writing a single line of SQL. On the other hand, it lacks some of the caching and performance benefits of a genuine object database management system, because although usually concealed by an API, type coercion between object types and native database types still has to take place. In contrast, a genuine ODBMS usually has a one-to-one mapping of object-to-database types, and therefore has no such performance hit.
But O/R mapping isn’t really a “killer app” in itself, so TierDeveloper tries to go a bit further, taking the object/table bindings you’ve specified and generating skeletal WinForms, WebForms, Web service, and remoting applications on request. The resulting applications can target SQL Server, Access, Oracle, and DB2 databases.
Boot up TierDeveloper, and you’ll be greeted by an IDE strikingly similar to Visual Studio. Assuming you’re connected to the Internet, the content pane will walk you through the process of creating a project (if you’re working offline, you’ll get the somewhat less helpful “This page cannot be displayed.”)
But you’re only a few mouse clicks away from a complete application. Use the File menu to start a new project, and TierDeveloper prompts you to select a database. When you select the database, TierDeveloper “acquires” a list of tables within it. All you have to do is click “Project?> Components?> Generate & Build” to create object mappings for each table, and then “Project?> WinForms Application?> Generate & Build” to produce a standalone executable. For various reasons I was unimpressed by the final applications TierDeveloper produced, but I’ll come to that in a moment. What struck me first was that TierDeveloper’s O/R mapping was based around a sensible object model, and a lot of thought had gone into making it as flexible as possible.
Mapped and Unmapped Objects
At the heart of any TierDeveloper project is its collection of “Objects” (capital O). These will ultimately be compiled into .NET classes, and you’ll use them to interact with the database. But TierDeveloper’s O/R mapping isn’t just database driven; it’s actually two-way. You can map objects from a database, or alternatively declare “unmapped objects” with appropriate properties and export DDL scripts to create the necessary database tables. The resultant objects usually represent one or more fields mapped from one or more tables, but you can also combine unmapped objects with a “User Defined” schema synchronization to produce auxiliary “non database” objects. Whichever approach you choose, you can then further refine the resultant .NET objects with additional queries, relationships, and stored procedures as described in the following sections.
|Author’s Note: Watch out! If you do create unmapped objects and choose to export DDL scripts for them, be sure to uncheck “Export Data Source tables” (checked by default) if you don’t want your database tables emptied of all their existing data when you run the resultant script.
For fine-grained control, you can add queries to the objects you’ve created. While you’re free to enter your own SQL explicitly, the process is wizard driven and the dialogs open with appropriate defaults and constraints. For example, if your query doesn’t involve a JOIN, you’re restricted to the data types already exposed by the object in question. If, on the other hand, you elect to JOIN another table, TierDeveloper tries to guess the correct foreign key and choose it automatically as a default. Having chosen the table bindings, you can enter an explicit WHERE clause if you want. Alternatively, you can elect to generate a “Dynamic Query”, meaning that the WHERE clause is supplied at runtime by the application.
You can also add one-to-one, one-to-many, and many-to-many relationships between the tables mapped by your objects. A nice touch is that if you check “Show only Related Objects,” TierDeveloper displays only the database tables that match the relationship you’ve selected, showing the column keys side by side. For many-to-many relationships, it cleverly attempts to identify the bridging table in question. I also liked the fact that if you try to add a relationship to a table that isn’t yet mapped, TierDeveloper offers to import a mapping for it automatically, before creating the relationship. The wizard is intelligent enough to detect improbable mappings (for example, if you try to map int to nchar), and issues an appropriate warning.
Stored Procedures and Bulk Operations
TierDeveloper lets you wrap stored procedures as method calls and add dedicated functions to update or delete records (based on an input parameter). The interface for doing this is similar to the one you use to create queries.
With a full set of mapped objects, you should be able to replace your legacy SQL with .NET objects whose methods and relationships manipulate and represent the database in the same way. It’s one thing to create objects based on a snapshot of a database table (or vice versa), but keeping those objects and the underlying database structures synchronized is typically more difficult; however, TierDeveloper makes this particularly easy. After linking a TierDeveloper project to a particular database, you can resynchronize the two at any point. This means that TierDeveloper propagates “online” changes to the database (e.g. manual updates via SQL Agent) to the “offline” TierDeveloper project, and “offline” changes to the project to the database. You can set synchronization on a per-object basis, or choose “User Defined” for standalone objects or those with complex synchronization semantics.
Class Libraries and Applications
TierDeveloper will produce class libraries for any objects you’ve mapped. It will also?optionally?produce Windows Forms, ASP.NET Web Forms, Web services, or remoting sample applications using your mappings. This is an important distinction because while TierDeveloper produces good and usable class libraries, I wasn’t nearly as impressed by the generated sample applications that hosted them. For example, the generated Windows Forms application failed to update the currently displayed record if it couldn’t find a match in the database, and the ASP.NET application generated non-fatal (but annoying) script errors whenever it tried to retrieve anything. Accordingly, while I’d unhesitatingly recommend TierDeveloper for its O/R capabilities, I’d also recommend that you avoid relying on the generated applications and develop your own applications around the class libraries from scratch; TierDeveloper’s various “Application” projects do not add value, and are likely to cause you frustration.
The Market for O/R Tools
I’m generally sympathetic to the idea of code templates to facilitate rapid prototyping, but the biggest problem I have with so-called “Enterprise” solutions such as TierDeveloper is not failure to deliver, but the things they take away. Code generation tools may save you time coding particular parts of an application, but it’s often difficult to write your own code alongside them, meaning that if you need features they don’t provide, or want to do things in a different way, you’re in a worse position than if you wrote your application from scratch. This is particularly the case when the RAD tool in question supplies its own runtime or API to support the code it produces. TierDeveloper, for example, builds applications against an assembly called EnterpriseServicedLib, although I suspect this is more to enforce licensing conditions than out of necessity. It also requires an assembly entitled TDevFramework, which provides (among other things) collection and serialization support.
If everything worked perfectly, I might be more sympathetic to both TierDeveloper’s API lock-in and its hefty price tag. As it is, despite the intelligence behind it, TierDeveloper remains a quirky production, and it’s impossible to overlook some of its frankly bizarre implementation details, like spawning regsvcs from the command line whenever you request a component rebuild (the resultant code lacks proper line endings, prompting Visual Studio to ask if you want to “normalize” them when you open the project externally). It’s also easy to tie yourself in knots if you fail to perform project tasks in the correct order, and the accompanying documentation is poorly written and riddled with typos.
Accordingly, make sure you download a trial version to see if it’s appropriate to your needs before burning your boats. There’s no doubt TierDeveloper is clever, and in the right hands it might well deliver on its promise to “develop real-life complex .NET database applications in record time.” But it’s unpolished, and at $1495 for a single license, you might reasonably feel you want more for your money. You might consider the Professional edition, at a third the price ($595), but note that, among other restrictions, this has limited Visual Studio Integration, supports only SQL Server, doesn’t allow dynamic queries, and won’t let you customize the GUI templates for the applications it creates.