
Jeff Germain and I have been doing some cool work with the geodatabase, and I'm going to summarize our work over a series of postings. This post introduces the key ideas...
Standard "Business Objects"In keeping with object-oriented design, most applications are now utilizing classes (business objects) to represent the real-world entities of concern to the application. When it comes time to store these entities in a database, the data access operations are typically bundled into the business objects themselves, or in associated helper classes. The advantages of this model are many, including:
- cleaner code design
- easier maintenance
- encapsulation of data storage logic
- single point for database schema changes
- with .NET 2.0, object data binding is possible (very cool)
There are many design options which take this model to various levels of complexity. You can find all sorts of information about Object Relational Mapping at
ORMappers.com
Geo "Business Objects"Since this is such a nice design pattern, we wanted apply the same logic to the geodatabase. Afterall, you design classes when you design a geodatabase, but the geodatabase API is cumbersome as compared to working with standard business objects.
To be clear - we're not talking about replacing IFeature and IRow, after all, you still need to talk to the geodatabase, and that's how ArcObjects works. But, in order to avoid working with the geodatabase API all over our code, we designed wrapper classes that hide the ArcObjects code behind a nice "business object" facade.
Some might ask - why would you go to all this trouble? The first part is that for large enterprise systems, where they may be 10 or more associated attribute tables related to one feature class, being able to work with a set of business objects greatly simplifies creation of attribute editing forms. And, if designed correctly, these objects could be used in Desktop, Engine and Server applications. The second part is that once you set it up, it's not much work. Which brings us to...
Code GenerationA nice thing about business objects is that they follow a pattern. And computers can do great things with patterns - like write the code for us. This is what code generation tools bring to the table. A typical code generation tool connects to the database, reads the schema, and creates classes based on code templates. This process takes a few seconds, and can be re-run at any time, and many teams add this as a step in their build process. Depending on the templates used, there are options where the developer can add custom logic which is not over-written when the code is re-generated (via inheritance or partial classes). As you may have guessed, this results in massive time savings when writing applications.
For example, I needed to create an application to edit the tables in a standard relational database (Process table shown above). Using
RapTier, I was able to create a complete data access layer in a few minutes. Once that part was done, I was able to very rapidly wire the business objects into an interface, and the application was complete. The image below shows the classes created for the "Process" table. You'll notice that these objects do not have "Get", "Save" or "Update" methods. In the abstration model used by RapTier, all these functions for all the classes in the database are in a single helper class.
But this is a Geodatabase...So, this works well for traditional RDBMS tables, but it's not going to fly for the geodatabase. First off, you can't infer all the details of a geodatabase model directly from database schema itself. Specifically, you'd miss thinks like relationships, domains and subtypes. Additionally, if you are working aginst ArcSDE you'll get all those pesky A, D, F, and S tables. Finally, the code that would be generated would use standard SQL (or stored procs) to insert and update the data. So, clearly we had some issues to work out.
Our Process
We've got two large projects on the go right now, and both are going to be subject to many geodatabase schema changes over their life span. To that end, we are working on a process where by we are able to generate business objects (and class extensions) directly from a geodatabase. The diagram below shows how this works, but the high-level steps are as follows:
- Export the geodatabase schema as Xml
- Transform that into a simplified Xml
- Use this simple Xml to generate the code
- Use object data binding in .NET 2.0 to simplify the form wiring
- Repeat when the schema changes
In the next installment, I'll review the process, the business object templates we've created and tools we've used to so this.