Posted By: Andrew Davey | Aug 5th, 2006 @ 3:51 PM
page 2 of 2
Comments: 31 | Views: 19443
JohnAskew
JohnAskew
9 girl in pink sweater
Tensor wrote:

JohnAskew wrote: I derive from BindingList<T> and prefer my own business objects over DataSets, DataTables, etc.

I was recently asked about the expense of iterating through a DataTable.DataRows to fill a custom collection.
I shrugged my shoulders.



Thats why I like datareaders!



Ah, yes, and I agree. We are going to re-design this app's DAL, right now it returns DataTables. I didn't think to mention that, left to my own devices, I use DataReader also.

Either way, I feel more comfortable with my own business object collections.
Seems like we nearly had the same inspiration. At http://nhibernate.fluffnstuff.org/ you can find a similar implementation targeted mainly at NHibernate users that want to databind nested collections. It also has basic sorting and searchnig support.
One of the reasons I like to use business entities over a dataset is that with the dataset you are still working with the data in a tabular fashion, which to me is less intuitive than an object hierarchy.

I also think that when properly implemented, a business entity can be more performant. For instance, a business object that represents a "customer" may have demographics, a collection of recent transactions made by the customer, etc. Using lazy load techniques the object is then optimized to pull only the necessary data for any given usage, and does so intrinsicly. They are more work to create up front, but in the long run I find that I don't have to introduce as much code as I would using multiple datasets in each context.
odujosh
odujosh
Need Microsoft SUX now!

Playing devils advocate here. What about the main purpose of a business object: The logic, events, and methods.

For those who use ADO.NET disconnected classes (DataTable, DataSet, DataView etc) How do you inject the flavor. Do you have Data___ as a member of class. Ala:

public class Person

{

DataTable m_PersonTable;

//.... other flavor

}


Or use a service based model that validates schema it needs to do x. Then does x using some kind of instancing mechanism.

Or inherit from X ADO.NET. Object and add methods. (Inheritance abuse Tongue Out)

I am a BussObj/ADO.NET translation guy that is kinda on the fence. I have done it both ways. Like to see how others have thrown together the puzzle peices. The performance really is not enough to get me to switch back. I like being able to go:

Orders Results = myPerson.GetOrders();

SynchOrderToUI(Results.Current.OrderInfo);

I like have the functionality pull down with my business object. You can do late binding with this as my example necessitates. (Pulling down every order myPerson made may take a bit of time in certain cases.Smiley

Josh



JParrish wrote:
One of the reasons I like to use business entities over a dataset is that with the dataset you are still working with the data in a tabular fashion, which to me is less intuitive than an object hierarchy.


If you're using a strongly typed DataSet configured with relations connecting all DataTables, the intuitiveness of the data is pretty comparable to a custom business object.

If you had two business objects: Customer and Order, you might retreive the orders for a customer using the following code:

Orders orders = customer.Orders;

Whereas the same functionality, using a strongly typed DataSet, might look like this:

CustomersDataSet.OrderRow[] orderRows = customerRow.GetOrderRows();

Both scenarios are done with the same number of lines, both can be enumerated and accessed with strongly-typed properites, and both are arguably intuitive in their own ways.

The difference is that it took two seconds to create the strongly typed DataSet and the same coding style can be used across all instances of DataSets regardless what they represent. With DataSets, you can easily make changes to them, and send them back to your DAL which in turn easily updates the changes using a DataAdapter. With a business object, you'd have to develop that logic yourself, which seems pointless, and depending on where logic is placed, can be rather nasty (I've seen some rediculous code done by developers in this area).

JParrish wrote:

I also think that when properly implemented, a business entity can be more performant. For instance, a business object that represents a "customer" may have demographics, a collection of recent transactions made by the customer, etc. Using lazy load techniques the object is then optimized to pull only the necessary data for any given usage, and does so intrinsicly.


All that business logic you just mentioned is well-suited for an actual business logic layer, not the business object itself.

I use DataSets strictly as containers of data that are passed between layers and controls. Any events, methods, logic, ect that I need to perform is done externally to the DataSet.

I think the biggest factor that decides which route you take is the underlying architecture your applications use. In my case, DataSets make perfect sense. I like communicating with my business logic layer and letting it retreive the data for me as opposed to calling a method directly on the business object itself, so I develop everything into the respective layers, and leave the DataSets alone, existing only for the purpose of containing the data.
LostInTangent wrote:

If you're using a strongly typed DataSet configured with relations connecting all DataTables, the intuitiveness of the data is pretty comparable to a custom business object.

If you had two business objects: Customer and Order, you might retreive the orders for a customer using the following code:

Orders orders = customer.Orders;

Whereas the same functionality, using a strongly typed DataSet, might look like this:

CustomersDataSet.OrderRow[] orderRows = customerRow.GetOrderRows();

Both scenarios are done with the same number of lines, both can be enumerated and accessed with strongly-typed properites, and both are arguably intuitive in their own ways.

The difference is that it took two seconds to create the strongly typed DataSet and the same coding style can be used across all instances of DataSets regardless what they represent. With DataSets, you can easily make changes to them, and send them back to your DAL which in turn easily updates the changes using a DataAdapter. With a business object, you'd have to develop that logic yourself, which seems pointless, and depending on where logic is placed, can be rather nasty (I've seen some rediculous code done by developers in this area).

All that business logic you just mentioned is well-suited for an actual business logic layer, not the business object itself.

I use DataSets strictly as containers of data that are passed between layers and controls. Any events, methods, logic, ect that I need to perform is done externally to the DataSet.

I think the biggest factor that decides which route you take is the underlying architecture your applications use. In my case, DataSets make perfect sense. I like communicating with my business logic layer and letting it retreive the data for me as opposed to calling a method directly on the business object itself, so I develop everything into the respective layers, and leave the DataSets alone, existing only for the purpose of containing the data.


Sorry about not replying directly to each block, its late.

I recall talking to you, or perhaps someone else about this. It is true that a strongly typed dataset can be seen as being similar to a hierarchy of business objects; when you are treating the business object purely as a data transport object.

In my designs, my business entities are not data aware. That is to say that they are not aware of any underlying data source. They represent entites within the domain as attributes as well as behaviour. Therefore, the business logic operates only on the various attributes of the objects within the model. At no point do any of my objects directly interact with data at a provider level. Not even to load their own data.

What I do instead, via a persistence coordination layer, is configure the providers for my business objects within a fairly simple XML mapping file. To get a business object populated the calling code passes an instance of the object to a "persistence coordinator". The persistence coordinator determines the appropriate provider from the configuration, activates the provider, and passes the object instance to the provider to be returned with data.

The approach I take has more advantages when looking at persistence out from the business objects. With a configuration change, my objects can be persisted to one or more endpoints. This allows me to create providers for Oracle, SQL Server, XML, etc. or if I chose to perform state dumps.
Datasets VS objects
One of things that makes me feel left out is how the InitializeComponent initialisation occurs and how it affects getting exisitng data (e.g serialized data perstisted as xml to the HDD) is populated...

I guess this down to how you expose the datasource... and implement it using the fantastic RAD approach of drag and drop...
How about creating a kind of factory component class?

I am looking to replicate the behaviour of what happens when you add a datasource to a project and then drag a datatable onto a form really...  The population which occurs via the tableadapter can be achieved by another class agreed...but....

A bindingsource bound to a dataset is bound to an instance of the dataset where as the object binding uses a typeof....

I can't find a best practive for this as yet...
this code is cut short for brevity...

private void InitializeComponent(){
//dataset

....

this.myDBDataSet= new winformdataviewdemo.myDBDataSet();

this.customerBindingSource = new System.Windows.Forms.BindingSource(this.components);

this.customerTableAdapter = new winformdataviewdemo.myDBDataSetTableAdapters.customerTableAdapter ();

this.customerBindingSource .DataMember = "customer";

this.customerBindingSource .DataSource = this.myDBDataSet;
........

///data bound object

this.customerObjectBindingSource.DataSource = typeof(objectclass.customerObject);

//this.customerObjectBindingSource.DataSource = customerObject1 ... would be nice

}

private void Form1_Load(object sender, EventArgs e){
this.customerTableAdapter .Fill(this.myDBDataSet.customers);
//Hey presto databound controls show the data

// so how about the customer object...?
//The constructor will not have been called yet...
//not until the bindingsource.add method is called...


}



page 2 of 2
Comments: 31 | Views: 19443
Microsoft Communities