wwBusiness: DataRow based Business Objects

I'll first create a DataRow based business object since that will show the process of creating the business object, then switch it to an Entity base control. The concepts are similar and Entity objects are based on the DataRow based objects.

To create a standard business object the process consists of:

  1. Adding a reference to the Westwind.BusinessObjects DLL to your project
  2. Creating a new class and inheriting it from wwBusiness
  3. Adding the Westwind.BusinessObject namespace
  4. Implementing the constructor for configuration of the business object

Adding a reference

To add the Westwind.BusinessObject.dll to your project go to the References section of the project and either add the DLL directly from the wwBusiness build directory or alternately you can open the wwBusiness project in your current solution and then add a reference to that project.

Add the namespace

You will also need to add the Westwind.BusinessObjects namespace to make sure that all members and related object members show up properly in your code via intellisense and compile properly. Do this by adding:

using Westwind.BusinessObjects;

above the namespace reference.

Creating a new Class

Create a new class in your project. By default classes inherit from Object which is shows no inheritance on the Class descriptor. Change this to:

public class busInvoice : wwBusiness

I like to prefix my business objects with a bus prefix so they are easy to discover in Intellisense and to avoid name overlap with framework level classes that might be confusing, but that's entirely up to you.

Implementing the constructor

Finally you need to implement a constructor and point it at a ConnectionString and ConnectType and database TableName at a minimum.

The following snippet demonstrates all of the steps:

namespace Westwind.WebStore { public class busCustomer : wwBusiness { public busCustomer() { // *** Preferrably set the connection string from a config store this.ConnectionString = App.Configuration.ConnectionString; // *** Primary mapped table this.Tablename = "wws_customers"; // *** Set new row values to 'blank' values rather than nulls this.NewRowBlankValues = true; // *** Use custom updates rather than DataAdapter this.DataRowUpdateMode = DataRowUpdateModes.OptimizedByPk; // *** Values set here only for reference - these are defaults this.ConnectType = ServerTypes.SqlServer; this.PkField = "Pk"; this.PkType = PkFieldTypes.intType; } } }

This creates a new business object with default data settings. Once these are set the business object is ready for use in your own code.

You should always set the connection string from some sort of configuration store that can be changed. This can be ConfigurationManager.ConnectionStrings - here I'm using the wwAppConfiguration manager and a application wide ConnectionString value to hold this value. You can also set this manually in your application of course but it's recommended this is done here for encapsulation.

The other thing that you typically will want to do is map the business object to a primary table in the database. This is the table that will automatically be used for CRUD operations. You also need to specify the primary key field and type of the Pk. The business object can handle creating new Pks for you, or your can override the CreateNewId() method to generate Pks of your own. By default wwBusiness uses Integer Pks and generates a new value using a stored procedure and reference table.

NewBlankRowValues is optional but used in all objects of the store - this sets all fields to default blank values rather than nulls to avoid update problems. Finally the tablename is explicitly set and mapped to an underlying database table that is used as the default table updated by this business object if you don't override Load, GetBlankRecord and Save methods.

Calling the Business Object

Once you've created the class you can easily instantiate it with:

busInvoice Invoice = new busInvoice();

Creating a Factory method

Although direct instantiation is easy, it's a good idea to create an intermediary method to provide an instance. This is known as a Factory and the Web Store provides a WebStoreFactory class for this. This class provides static members for each of the classes in the store as to provide a single point of object creation. This is useful if you at some later point decide to subclass a business object and want to have the new subclass be used throughout the application.

To create a Factory method you'd use the WebStoreFactory class for example and implement:

public class WebStoreFactory public static busInvoice GetbusInvoice() { return new busInvoice(); } }

If at some point in the future you decide to subclass busInvoice into busMyNewInvoice you change that to:

public static busInvoice GetbusInvoice() { return (busInvoice) new busMyNewInvoice(); }

which makes sure that existing code still works just fine. Anytime you need the new functionality you can then simply case the object to your specific business object type:

busInvoice Invoice = WebStoreFactory.GetbusInvoice(); busMyNewInvoice MyInvoice = Invoice as busMyInvoice;

At this point you're ready to use the business object in your application. The following demonstrates a few things you can do:

public string DataRowBusTest() { busInvoice Customer = new busCustomer(); // *** Execute query and load into TCustomers Table of internal DataSet if (Customer.Execute("select * from " + Customer.Tablename, "TCustomers") = -1) { this.lblErrorMessage.Text = Customer.ErrorMessage; return false; } int Count = Customer.DataSet.Tables["TCustomers"].Rows.Count; // *** Load a customer by pk - load DataRow property if (!Customer.Load(1000)) { this.lblErrorMessage.Text = Invoice.ErrorMessage; return false; } // *** Read some values string Company = (string) Invoice.DataRow["company"]; decimal Entered = (DateTime) Invoice.DataRow["entered"]; // *** Update data Customer.DataRow["Updated"] = DateTime.Now.Date; if (!Customer.Save()) { this.lblErrorMessage.Text = Customer.ErrorMessage; return false; } // *** Creating a new customer Customer.New(); // *** New Pk value is generated before data is saved int Pk = (int)Customer.DataRow["pk"]; Customer.DataRow["company"] = "West Wind"; Customer.DataRow["address"] = "32 Kaiea"; Customer.Save(); // *** Delete a customer by pk Customer.Delete(Pk); return true; }



 Last Updated: 3/4/2007 | Send topic feedback