Monthly Archives:

Welcome to OPF3

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.