Click here to Skip to main content
6,292,426 members and growing! (10,263 online)
Email Password   helpLost your password?
Database » Database » General     Intermediate

Persistent Object Management in less than 300 Lines of Code

By Nick Higgs

Presenting a lightweight method to cut out most of the repetetive work of creating data classes.
SQL, C# 2.0, Windows, .NET 2.0, ASP.NET, Visual Studio, WebForms, SQL 2000, SQL 2005, Architect, DBA, Dev
Posted:9 Apr 2007
Updated:8 Oct 2007
Views:41,108
Bookmarked:57 times
Unedited contribution
Announcements
Loading...
 
Search    
Advanced Search
printPrint   Broken Article?Report       add Share
  Discuss Discuss   Recommend Article Email
14 votes for this article.
Popularity: 4.51 Rating: 3.93 out of 5

1
2 votes, 14.3%
2
2 votes, 14.3%
3
3 votes, 21.4%
4
7 votes, 50.0%
5

Introduction

There's a lot of repetitive work associated with the writing of data classes within the data access layer of an N-tiered architecture. Apart from adding a column to the relevant database table, adding a field to the class involves adding a private variable to hold the field value, a property to expose it to other classes, and several lines to make sure the field is included in insert, fetch, and update operations. If you're using stored procedures (very silly for CRUD queries) that several more modifications to make. This is dull work I'm sure you'll agree. Presented here is a lightweight method for taking away all this tedium, such that you only have to add a getter/setter property in order to add a field to a data class.

The technique involves abstracting SQL query writing and execution, and variable storage in data access classes to a base class. In the implementation presented here I've named this base class "PersistentDataObject". The "less then 300 lines of code" referred to in the title of this post are the lines of code in this base class, the database access class it uses, and a couple of exception classes used as markers to add clarity to exception origins. The complete code is included at the end of the post.

Background

I conceived of this idea, before my .Net days, while working on a monolithic PHP project. After writing hundreds of simple CRUD queries that were all basically the same I realized that it would be a simple matter to abstract all that query writing in such a way that I would never have to write such a simple query again. That was over a year ago. Now I'm a fully paid up ASP.Net developer, and I think the code has reached a level of refinement at which it is ready to be presented to the world. I use the code presented here in every system I build and I love it. Maybe you will too.

Using the code

Here is a simple Person class created by extending PersistentDataObject:

using System;

public class Person : PersistentDataObject
{
 public Person() : base("Person", "PersonId") { }
 public Person(int id) : this() { Load(id); }

 public string FirstName
 {
   get { return Get<string>("FirstName"); }
   set { Set("FirstName", value); }
 }
 public string LastName
 {
   get { return Get<string>("LastName"); }
   set { Set("LastName", value); }
 }
 public DateTime DateOfBirth
 {
   get { return Get<DateTime>("DateOfBirth"); }
   set { Set("DateOfBirth", value); }
 }
 public int? LuckyNumber
 {
   get { return Get<int?>("LuckyNumber"); }
   set { Set("LuckyNumber", value); }
 }
}

Configuring the Data Object Class

The only configuration values necessary for the class are name of the table from which the data is to be retrieved, and the name of the unique id column within that table (assumed to be an integer column). These are passed to PersistentDataObject in the constructor.

public Person() : base("Person", "PersonId") { }

Fetching Data from the Database

The Person class shown above provides a constructor that accepts a integer identifier as an argument. This constructor delegates to the Load method of PersistentDataObject to fetch all data from the database for the row with the specified identifier.

public Person(int id) : this() { Load(id); }

An overload of the Load method is provided that takes a DataRow as an argument. This allows the object to be populated with data from a DataRow that has already been fetched from the database.

Exposing Column Values as Properties

Column Values are exposed by delegating to the Get and Set methods of PersistentDataObject. The Get method takes a string argument indicating the column from which the value should be retrieved. Similarly, the Set method takes a string argument to indicate for which column the value is to be set. This example shows a property exposing a DateTime column:

public DateTime DateOfBirth
{
get { return Get<DateTime>("DateOfBirth"); }
set { Set("DateOfBirth", value); }
}

Note that the Get method uses generics to identify the type of the value that should be returned. The type specified should be the appropriate type dependant on the type of the column.

Handling null values

Nullable value types come into play in order to handle columns that allow null values. This example shows an integer column for which null values are allowed exposed as a property:

public int? LuckyNumber
{
get { return Get<int?>("LuckyNumber"); }
set { Set("LuckyNumber", value); }
}

Note that as string is a reference type, it does not need to be specified as nullable to accept null values.

Inserting, Updating, and Deleting

A Save method is provided that handles both the inserting into, and the updating of objects in the database. If the Save method is called on an object that does not yet exist in the database, then an insertion is performed. If the object does already exist in the database, an update is performed. This code snippet shows an instance of Person being created and that a record for it being inserted into the database:

Person person = new Person();
person.FirstName = "Nick";
person.LastName = "Higgs";
person.DateOfBirth = new DateTime(1983, 2, 7);
person.Save();

A Delete method is provided to allow the object to be deleted from the database. This code shows an object for and existing person record being instantiated and then deleted from the database:

Person person = new Person(51);
person.Delete();

Closing remarks

That completes the explanation. I've found that this technique not only takes most of the repetitive work out of writing data objects, but provides a solid foundation to a data access layer, regardless of the complexity of the system.

History

Modified from an article posted on my blog:
http://developmental-issues.blogspot.com/2007/04/simple-or-mapping-in-less-than-300.html

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Nick Higgs


Member
Since graduating from the University of Sheffield with a Masters degree in Software Engineering in 2005 I have been woking as a professional web developer for a Sheffield new media company.
ASP.Net is currently my primary technology, but I also have substantial experience with PHP and Flex and various Java technologies.
Occupation: Web Developer
Location: United Kingdom United Kingdom

Other popular Database articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 25 of 35 (Total in Forum: 35) (Refresh)FirstPrevNext
QuestionMultiple object Pinmembersuraj Chhetry21:56 9 Oct '07  
AnswerRe: Multiple object PinmemberNick Higgs3:25 10 Oct '07  
GeneralInitiative way! PinmemberM.Khadem5:31 7 Jun '07  
GeneralHow to bind the Person object to a view object PinmemberAliasncnu17:43 7 May '07  
GeneralRe: How to bind the Person object to a view object PinmemberNick Higgs13:12 9 May '07  
GeneralQuestions and suggestions Pinmemberfelipedr7:16 19 Apr '07  
GeneralRe: Questions and suggestions PinmemberNick Higgs14:25 19 Apr '07  
GeneralTransactions Pinmemberprobe530:05 19 Apr '07  
GeneralRe: Transactions PinmemberNick Higgs10:30 19 Apr '07  
GeneralExcellent Article PinmemberDewey21:02 9 Apr '07  
GeneralRe: Excellent Article PinmemberNick Higgs3:07 10 Apr '07  
General2 security flaws Pinmemberreinux18:21 9 Apr '07  
GeneralRe: 2 security flaws PinmemberNick Higgs2:53 10 Apr '07  
GeneralRe: 2 security flaws PinmemberNick Higgs12:06 12 Apr '07  
GeneralRe: 2 security flaws Pinmemberreinux15:16 12 Apr '07  
GeneralRe: 2 security flaws PinmemberNick Higgs3:20 14 Apr '07  
GeneralRe: 2 security flaws Pinmemberreinux13:06 16 Apr '07  
QuestionStored Procedures "silly" for CRUD operations? Pinmemberchmod75511:10 9 Apr '07  
AnswerRe: Stored Procedures "silly" for CRUD operations? PinmemberNick Higgs14:09 9 Apr '07  
GeneralRe: Stored Procedures "silly" for CRUD operations? Pinmembermr_lasseter16:44 9 Apr '07  
GeneralRe: Stored Procedures "silly" for CRUD operations? Pinmemberreinux18:38 9 Apr '07  
GeneralRe: Stored Procedures "silly" for CRUD operations? PinmemberNick Higgs10:25 10 Apr '07  
GeneralRe: Stored Procedures "silly" for CRUD operations? Pinmemberreinux11:52 10 Apr '07  
GeneralRe: Stored Procedures "silly" for CRUD operations? PinmemberNick Higgs13:43 10 Apr '07  
GeneralRe: Stored Procedures "silly" for CRUD operations? Pinmemberreinux3:49 11 Apr '07  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 8 Oct 2007
Editor:
Copyright 2007 by Nick Higgs
Everything else Copyright © CodeProject, 1999-2009
Web16 | Advertise on the Code Project