OOP n-tier Question

  • Thread starter Thread starter Ale K.
  • Start date Start date
A

Ale K.

Hi, i'm designing my application that has a DLL that controls the Data
Layer, and another that Controls the Bussines Layer, at some point my
Bussines Layer need to Get an object ( Let's say a person ) that is
currently on a DB as a field on a table.
My question is, is it correct to have my Data Layer return a DataTable to my
Bussines Layer, and with that data fill the object, or this is commonly
implemented on another way??

Thanks.
Alex.
 
Alex,

I do the same thing, yes I return either a datatable or a datarowcollection
(data table if you think about it) or just a data row depending on what
function I'm doing.

So your fine... you could do it in your own classes, but then again, a
dataset is a class. =)

-CJ
 
Ale,
Returning a DataTable from the Data Tier is one of many patterns you can
follow.

Martin Fowler's book "Patterns of Enterprise Application Architecture" from
Addison Wesley has a number of patterns and how to implement them. The
samples in the book are Java & C#, however they can easily be translated
into VB.NET.
http://www.martinfowler.com/books.html#eaa

Rockford Lhotka's book "Expert One-on-One Visual Basic .NET Business
Objects" from A! Press provides a more Object Oriented approach.
http://www.lhotka.net/

Hope this helps
Jay
 
Ale K. said:
Hi, i'm designing my application that has a DLL that controls the Data
Layer, and another that Controls the Bussines Layer, at some point my
Bussines Layer need to Get an object ( Let's say a person ) that is
currently on a DB as a field on a table.
My question is, is it correct to have my Data Layer return a DataTable to my
Bussines Layer, and with that data fill the object, or this is commonly
implemented on another way??


I almost always create wrapper classes (or structures), because they are
much less of a headache to deal with when stuff changes (such as field
names). When you change the name of a class to reflect the changes in the
database, you will almost always get a compile exception, and the exact line
where the code needs to be updated. You also can access fields (or
properties) easier, you have the added advantage of intellisense, and this
way you don't need to think about how the actual table is named.

When you use a dataset, you are removing intellisense & the pre-processor
from the picture. This is a bad thing, it means that when the database is
changed, you must go through every single line of code that *might* have
accessed data from the table in question. Since the field names are in
quotes, the compiler has no way to know if it is an error or not, and 9
times out of 10, your user ends up finding the error before you do (in large
apps).

When you request items from a table, how many are you generally searching
for? Usually it is a finite number that can easily be translated into
objects in an array or collection. When you search for large numbers of
records, you still have options, but I would say it's best to keep the data
in a datatable so you don't waste tons of memory. But in these cases, you
usually are loading the data into a DataGrid, and don't care too much about
the actual field names anyway (for display purposes).

I also create wrappers for my stored procedures, so my functions usually
look something like this:

WmxData.Inventory.GetInventory(InventoryID as String)
WmxData.Inventory.GetInventoryObj(InventoryID as String)

The first returns a DataTable, and the second returns an InventoryItem
Object. I _never_ write T-SQL in my code, every single call is executed in a
stored procedure. So the wrapper for the stored procedure totally
encapsulates the call to SQL Server, loading a DataReader, and translating
the data into an Inventory Object or returning a DataSet / Table. Another
example:

WmxData.Inventory.MoveItem(InventoryID, NewLocation, Quantity)

So in this case, my stored proc actually handles all business logic to move
an item from one location to another. And when rules are broken, I throw a
custom exception from inside my proc so that the error bubbles up to my VB
code (which is then handled).

Furthermore, I have a class inside the "inventory" class that lists all my
procedure names:

Public Class Inventory
Private Class Procedures
Public ReadOnly GetInventoryByID as String =
"sp_inv_get_InventoryByID"
End Class
...
Public Function GetInventory(InventoryID) As InventoryItem
Dim p(0) as SqlParameter
Dim dr as DataReader
p(0) = New SqpParameter("@inventory_id", InventoryID)
dr = SqlServer.Execute( Procedures.GetInventoryByID, P, ...)
... translate the object and return it ...
End Function
...
End Class

Well, this post is way too long, so if you have questions, just ask (and I
will shut up now).

HTH,
Jeremy
 
"This is a bad thing, it means that when the database is
changed, you must go through every single line of code that *might*
have
accessed data from the table in question. Since the field names are
in
quotes, the compiler has no way to know if it is an error or not..."


To get past this when using datatables/views, I will assign the column
names to constants so that if the field names ever do change, I only
need to change them in one place in code:

' plate records
Public Const COL_PLATE_ID As String = "PLATE_ID"
Public Const COL_PLATE_IDENT As String = "PLATE_IDENT"
Public Const COL_PLATE_DESC As String = "PLATE_DESCRIPTION"

Then use them like this.

strPlateID = dv(0)(COL_PLATE_ID)
txtPlateIdent.Text = dr(COL_PLATE_IDENT)

or whatever...

They also come in handy when creating DataGridColumnStyles to display
your data in a datagrid.

You could also use Enums and refer the column ordinals...
 
Slonjo,
Speaking of DataGridColumnStyles. There are also DataColumnMappings &
DataTableMappings which are part of the DataAdapter.

Which means if the field name changes in the DataBase you can isolate it to
the DataAdapter, thus preventing the change from percolating into your
DataSet. They are also useful to map your Database standard names to
DataTier standard names which would are nicer for Typed DataSets.

See:
DataTable.TableMappings property
DataTableMappingCollection class
DataTableMapping class
DataColumnMappingCollection
DataColumnMapping Class

Of couse DataColumnMapping will not help with changed field types and
addition or subtraction of fields.

Hope this helps
Jay
 
Back
Top