OPF3: The Painless ORM
I've been working with OPF3 for the past three years and I
tell you, it has been a huge time saver. During my schooling, the
standard method for manipulating a database would include writing
SQL stored procedures, and then write methods within your data
access layer to communicate with these stored procedures. Return
values, @@IDENTITY, and methods taking lengthy parameters are all
but a thing of the past, thanks to OPF3. When I was first introduced to
OPF3, my first and initial thoughts were "huh?" and "what's wrong
with stored procedures?
First of all, there is nothing wrong with stored procedures. In
fact I still use them alongside the OPF3
framework. OPF3 isn't without its limitations
though. Currently there is no support for return values. OPF3
was designed as a lightweight ORM (Object Relationship Manager) to
eliminate mundane coding.
How does OPF3 work?
Imagine each table in your database as an object. For every
table you have an object equivalent in your application. And just
as you might expect, each object would have properties that map to
the corresponding column in your database. It's a pain free
process. Here's a tiny example of what such a class would look
like.
[Persistent( "WebUsers" )]
public class WebUser :ISelfContainingObject
{
[Field( "Id", Identifier = true, AutoNumber = true, AllowDBNull = false )]
public int Id { get; set; }
[Field( "Login", AllowDBNull = false )]
public string Login { get; set; }
[Field( "FirstName", AllowDBNull = false )]
public string FirstName { get; set; }
[Field( "LastName", AllowDBNull = false )]
public string LastName { get; set; }
[Field( "SALT", AllowDBNull = false )]
public string SALT { get; set; }
[Field( "HASH", AllowDBNull = false )]
public string HASH { get; set; }
[Field( "CreateDate", AllowDBNull = false )]
public DateTime CreateDate { get; set; }
[Field( "Status", AllowDBNull = false )]
public int Status { get; set; }
private ObjectInfo _ObjectInfo = new ObjectInfo();
public ObjectInfo ObjectInfo
{
get { return _ObjectInfo; }
set { _ObjectInfo = value; }
}
}
As you can see from my WebUser class, I've got full control of
all columns in the WebUsers table. Now inserting / updating is as
easy as this!
public enum eWebUserStatus
{
Active,
Pending,
Inactive
}
public void btnSaveWebUser_Click( object sender, EventArgs args )
{
//instansiate our WebUser class and assign the variables
WebUser newUser = new WebUser();
newUser.FirstName = "Matt";
newUser.LastName = "Tycholaz";
newUser.Login = "matty";
newUser.CreateDate = DateTime.Now;
newUser.SALT = Tools.GenerateSALT();
newUser.HASH = Tools.GenerateHASH( newUser.SALT + "secretpassword" );
newUser.Status = ( int ) eWebUserStatus.Pending;
try
{
//do an insert using a transaction
using ( Chili.Opf3.Storages.Transaction t = ObjectContextFactory.ObjectContext.StartTransaction() )
{
//push our changes into the database
ObjectContextFactory.ObjectContext.PersistChanges( newUser );
//commit the transaction
t.Commit();
}
}
catch ( Exception ex )
{
//if an error occurs then display it
MessageDisplay.DisplayMessage( ex );
}
}
Stay tuned for my next post where I'll show you more advanced
scenarios.