Solved

Passing data from DAL to BLL to PL using vb.net in winforms

Posted on 2010-09-15
27
1,950 Views
Last Modified: 2012-05-10
Hi Experts,
I am designing  a desktop app using VS 2008 and MS Access.  It is going to be a 3-tier app.  I am experimenting different things that my app will need.  For example,
My Form(PL) has this combobox. UI will call BL to get All the Product Categories, assign Combobox.Datasource= BL.GetCategories(list or array())
Product Categories has attributes like Category_Name, Category_ID, Category)Type etc.

BL will ask the DAL to get the categories from the Access database. Can I use arrays or lists to be passed to BL? How do I pass objects (class)
 I want to keep these three layers as independent as possible, so in future we make it Web based, my PL will only change. if we use SQL server instead of Access, only DAL will change. If we change business rules, only BLL will change.
I have been searching the net for last two days,but cannot find sample code for VB.NET AND Winforms, or simple enought to understand.
So the question is : how do I implement DA so that it passes class or list or array
How does the BLL pass this data to PL
, And in PL(form level) how do i populate Combobox(Dropdown List)  using it's datasource property? This combobox will have Category Name as display Item and Category_Id as tag(? )(Itemdata in vb6 world).

This will be my basic building block and from this, I can build more complicated routines.
I will greatly appreciate if you can provide me a small but complete sample code in vb.net. for Winforms . Thanks in advance.

I
0
Comment
Question by:RekhaShah
  • 11
  • 11
  • 5
27 Comments
 
LVL 18

Expert Comment

by:DarrenD
Comment Utility
Hi,

The PL can be any client app such as web page, silverlight or winform.

The BL is where all the rules are stored

The DAL is what you use tyo access the database.

Your best way to make all of this work is to either use .NET Remoting, Web Services or WCF.

Personally I would use WCF. This would sit between PL and BL so the system would be as follows

PL <-> WCF <-> BL <-> DAL <-> Database(Access, SQL Server, Oracle)

You can host WCF services in IIS which is probably the easiest way to get started (IMO).

If you are only ever going to have .NET PL then I would use generic List(Of T) to pass objects (classes) back and forth. If you might have a Java PL then you would probably have to use normal arrays (as far as I'm aware).

To populate a Combo you can use

            cboStaff.DisplayMember = "FullName"
            cboStaff.ValueMember = "UserName"
            cboStaff.DataSource = _employees

_employees is this case id a List (Of Employee)

Here are some links

http://www.c-sharpcorner.com/Articles/ArticleListing.aspx?SectionID=1&SubSectionID=192

Hope this helps,

Darren
0
 
LVL 18

Expert Comment

by:DarrenD
Comment Utility
Hi,

This is probably the easiest to get you started

http://www.c-sharpcorner.com/UploadFile/378f37/2577/

Cheers,

Darren
0
 
LVL 7

Expert Comment

by:klakkas
Comment Utility
The way to go is the following:

In the DAL, create a ProductCategory Class and use this to return your Data to the BL. Example:

Public Class DAL

    Public Class ProductCategory
        Public ID As Integer
        Public Name As String
        Public Category As String

        Public Sub New(ByVal newID As Integer, ByVal newName As String, ByVal newCategory As String)
            ID = newID
            Name = newName
            Category = newCategory
        End Sub

        Public Sub New()

        End Sub


    End Class


    Public Shared Function GetProductCategories(ByVal Params As String) As List(Of ProductCategory)
        Dim Res As New List(Of ProductCategory)
        'Get the data from the DB
        Dim dt As DataTable = ExecSelectCmd("Select * from ProductCategories")

        'Populate the result
        For Each r As DataRow In dt.Rows
            Res.Add(New ProductCategory(r("Id"), r("Name"), r("Category")))
        Next

        'Return
        Return Res

    End Function

    Private Shared Function ExecSelectCmd(ByVal sSql As String) As DataTable
        Dim dt As DataTable
        'Go get the data from DB
        Return dt
    End Function

End Class

In the BL, you also need to re-create the ProductCategory Class, keeping in mind that this will be the one that the PL will be using. For this reason, you should probably use Properties instead of Public  variables and definitely Override the toString function. Example:

Public Class BL

    Public Class ProductCategory
        Public ID As Integer
        Public Name As String
        Public Category As String

        'If you want, you can set these parameters to Private and use Properties to expose them

        Public Sub New(ByVal newID As Integer, ByVal newName As String, ByVal newCategory As String)
            ID = newID
            Name = newName
            Category = newCategory
        End Sub

        Public Sub New()

        End Sub

        'Use this ToString Override, in order to have the object shown as you want in the combobox
        Public Overrides Function ToString() As String
            Return Name + " (" + Category + ")"
        End Function
    End Class

    Public Shared Function GetBL_Categories(ByVal Params As String) As List(Of ProductCategory)
        'Process the params

        Dim tempRes As List(Of DAL.ProductCategory) = DAL.GetProductCategories(Params)

        'Tricky Part: Convert the DAL.ProductCategory to BL.ProductCategory
        Dim Res As New List(Of BL.ProductCategory)
        For Each PC As DAL.ProductCategory In tempRes
            Res.Add(New BL.ProductCategory(PC.ID, PC.Name, PC.Category))
        Next

        'Do your business logic here


        Return Res
    End Function

End Class

Finally, in your PL (any type of it, WinForms, WebSite, etc) you can easily consume the BL result as follows:

Fill the combobox
ComboBox1.items.AddRange(BL.GetBL_Categories(myParams).toArray)
Remember that the text that will be visible for each item will be the result of the Overriden ToString function of the Class

Get the Selected ProductCategory
dim SelectedProd as BL.ProductCategory = ctype(ComboBox1.SelectedItem, BL.ProductCategory)

Let me know if any part of this needs more clarification
0
 

Author Comment

by:RekhaShah
Comment Utility
you said,
    'If you want, you can set these parameters to Private and use Properties to expose them...
i created public properties with private variables like mn_CategoryName, mn_categoryID etc
How do you modify
Public Sub New(ByVal newID As Integer, ByVal newName As String, ByVal newCategory As String)
            ID = newID
            Name = newName
            Category = newCategory
        End Sub

        Public Sub New()

        End Sub
 to use properties insted of  public var ID, Name etc? Please bare with me, I amstrill trying to grasp the whle concept of Object oriented programming.
0
 
LVL 7

Expert Comment

by:klakkas
Comment Utility
No need to modify anything...

Full class is the following:
Public Class ProductCategory

        Private mn_ID As Integer

        Private mn_Name As String

        Private mn_Category As String



        Public Property ID() As Integer

            Get

                Return mn_ID

            End Get

            Set(ByVal value As Integer)

                mn_ID = value

            End Set

        End Property



        Public Property Name() As String

            Get

                Return mn_Name

            End Get

            Set(ByVal value As String)

                mn_Name = value

            End Set

        End Property



        Public Property Category() As String

            Get

                Return mn_Category

            End Get

            Set(ByVal value As String)

                mn_Category = value

            End Set

        End Property

        

        Public Sub New(ByVal newID As Integer, ByVal newName As String, ByVal newCategory As String)

            ID = newID

            Name = newName

            Category = newCategory

        End Sub



        Public Sub New()



        End Sub



        'Use this ToString Override, in order to have the object shown as you want in the combobox

        Public Overrides Function ToString() As String

            Return Name + " (" + Category + ")"

        End Function

    End Class

Open in new window

0
 
LVL 7

Expert Comment

by:klakkas
Comment Utility
The alternative would be to have the New Function write directly to the parameters, ex:

Public Sub New(ByVal newID As Integer, ByVal newName As String, ByVal newCategory As String)
            mn_ID = newID
            mn_Name = newName
            mn_Category = newCategory
        End Sub

But there is no need to do this, let the property do the writting.

Don't hesitate to ask if you need anything else.
0
 

Author Comment

by:RekhaShah
Comment Utility
Thanks, Klakkas for your prompt reply. I will try to implement this and get back to you asap. So i don't need the following coe if i am using properties?
Public Sub New(ByVal newID As Integer, ByVal newName As String, ByVal newCategory As String)
            ID = newID
            Name = newName
            Category = newCategory
        End Sub

        Public Sub New()

        End Sub
 
Or do I use the following like you suggested in your code?
Public Sub New(ByVal newID As Integer, ByVal newName As String, ByVal newCategory As String)
            mn_ID = newID
            mn_Name = newName
            mn_Category = newCategory
        End Sub

        Public Sub New()

        End Sub
 

Why do i need an empty Sub New? and Why do I need Sub New with parameters?
 
0
 
LVL 7

Expert Comment

by:klakkas
Comment Utility
If you don't declare any Sub New, an empty one is created automatically.

If you do declare a Sub New with parameters, the empty one is not created automatically, you should create it manually.

Now, regarding the need for them, it is simple: Having a new with parameters allows you to declare the object in one single line:
       dim Obj as New ProductCategory(5,"Kyriakos","Developer").
Without it, you would need 4 lines:
       dim Obj as new ProductCategory
       Obj.ID = 5
       Obj.Name = "Kyriakos"
       Obj.Category = "Developer"

It is simply a matter of writting less code...
0
 
LVL 7

Expert Comment

by:klakkas
Comment Utility
Oh, and regarding the 2 versions of the Sub New with parameters, I suggest using the first one, which uses the Properties to update the variables.

Public Sub New(ByVal newID As Integer, ByVal newName As String, ByVal newCategory As String)
           ID = newID
           Name = newName
           Category = newCategory
       End Sub

0
 
LVL 18

Expert Comment

by:DarrenD
Comment Utility
You could also do the following:

      Public Sub New(ByRef obj as ProductCategory)
           ID = obj .newID
           Name = obj .newName
           Category = obj .newCategory
       End Sub

and this should be quicker as you do not have to make a call to the property.

      Public Sub New(ByRef obj as ProductCategory)
           mn_ID = obj .newID
           mn_Name  = obj .newName
           mn_Category  = obj .newCategory
       End Sub

Darren
0
 

Author Comment

by:RekhaShah
Comment Utility
Thank you very much. It worked like a charm!
I really don't know what would I do without you guys out there willing to help! This is exactly what I needed.
Last question :
I still wonder, Why do I have to repeat properties in BLL and DA layers?  If I need to modify/add,delete any of the properties, I have to maintain at two places. This was a simple example, but when i have about 50 prioperties of an object, would i follow the same logic/Pattern? Can I have a Category class, define all the properties and inherit that class in both DA and BLL layers? If I can, how would I?
0
 
LVL 18

Expert Comment

by:DarrenD
Comment Utility
Should be

      Public Sub New(ByRef obj as ProductCategory)
           mn_ID = obj .ID
           mn_Name  = obj .Name
           mn_Category  = obj .Category
       End Sub
0
 
LVL 18

Expert Comment

by:DarrenD
Comment Utility
Hi,

The fact is that you should not really be just reiterating code. For example if you had about 50 properties then you should only be sending the ones that you need for the piece of functionality. For this I would create a smaller class which would be the subset that you needed and send these down to the client instead of the entire 50.

Also in the database you may have a list of values such
1 = EURO
2 = STERLING
3 = USD

If you stored the record in the database as an int then you can convert the int into the string value in the business layer so that the PL does not have to know how to convert 1 to EURO.

Cheers,

Darren
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:RekhaShah
Comment Utility
I have three directories in my project PL: has all the forms .BLL has all the business logic for each of my objects like ProductCategory,Customer, Vendor etc. DA has all the corrresponding DA routines. i alsohave onc commoneDA file that has allt he excuete,openConn, closeConn etc routines.
If I define a new class call  " Product" , and all it has is all the properties like name, id,category etc. This will be  in another folder. right? And in business layer s well as DA layer, I will just declare this Product call as local object and go forward like Klakkas suggested?
Can you give me a detail sample code please?
0
 
LVL 7

Expert Comment

by:klakkas
Comment Utility
If you want to go like this, then you should build a DLL with all your objects (products, Customers, etc) and declare their Classes, Properties, ToString Overrides, etc there.

Having done that, this DLL should be referenced from all 3 layers of your application, so that the can communicate using these classes.

Assuming that the DLL is named ObjDeclaration, the code should look like this :

DLL:
Public Class ObjDeclaration
    'Declare all your parameters, properties, Functions, New constructors, ToString Overrides, etc
End Class

DAL (Declaration only, the code remains the same):
 Public Shared Function GetProductCategories(ByVal Params As String) As List(Of ObjDeclaration.ProductCategory)

BL:
Public Shared Function GetBL_Categories(ByVal Params As String) As List(Of ObjDeclaration.ProductCategory)

        Dim Res As List(Of ObjDeclaration.ProductCategory) = DAL.GetProductCategories(Params)
       
        'Business logic here

        Return Res
End Function

PL:
Fill the combobox
ComboBox1.items.AddRange(BL.GetBL_Categories(myParams).toArray)

Get the Selected ProductCategory
dim SelectedProd as BL.ProductCategory = ctype(ComboBox1.SelectedItem, ObjDeclaration.ProductCategory)

As you can see, the layers use ObjDeclaration.ProductCategory to communicate. The only drawback is that the DAL is not completely independant from the rest of the application, since it relies on the common ObjDeclaration DLL.

0
 

Author Comment

by:RekhaShah
Comment Utility
Would you recommand that I take this route(wigh DLL)   or just  do it the way you suggested  in the first place?  i am going to build one object the right way. and then just dopy and paste the rest of the objects in the system. So I would rather spend more time upfront and do it the right way. Due to my inexperience, I need your advice.
Actually, I am converting a vb6 application that goes thru lot of changes (adding more objects, changing rules, changing database etc). My 90% of the time is spent in maintaining the app, if i fix one thing, it will break 10 more. My boss agreed to let me rewrite this app, so i better do it right :)
0
 
LVL 7

Expert Comment

by:klakkas
Comment Utility
Personally, I would go with the ObjectDeclaration DLL, especially since you are working with a small team.

Just make sure you declare the Objects very carefully from the start, because if for example (some time in the future) you need one extra field for the BL, you with have to rebuild the DAL as well (since the referenced DLL will have change).

Good luck!
0
 

Author Comment

by:RekhaShah
Comment Utility
Ok, i will build ObjectDeclaration DLL.
Like I mentioned earlier,  all BLL, PL and DA are just the folders in my single project solution. so when I make changes to the DLL, I will be building my project any way so, it will affect all the layers. right? Or would you recommand, I have three different projects - BLL,PL and DA  of the same solution?
i am a one member team who wares all the hats.
0
 
LVL 7

Accepted Solution

by:
klakkas earned 500 total points
Comment Utility
Seperate projects, definitely seperate projects.

DAL, BLL and ObjectDeclarations as DLLs and the PL as widnows Application.

This way, when you want to create a web site, you create the ASP project and add the 3 references.

Further, if in the future you want to change your DAL to talk (for example) with Oracle, and you have a collegue who is willing to help you, you only give him the DAL, not your entire code.
0
 

Author Closing Comment

by:RekhaShah
Comment Utility
Thank you very much for all your help. i have much clearer idea about the objects.
0
 

Author Comment

by:RekhaShah
Comment Utility
Sepearate DLL for each object  but one project. right?
0
 
LVL 7

Expert Comment

by:klakkas
Comment Utility
Hello RekhaShah,

sorry for the delay, but I don't work on weekends! :-)

Each DLL is a different project. All the projects are under the same solution.

So, when you will actually deploy the application to a customer, you will install (at least) 1 exe and 3 dll files.
0
 

Author Comment

by:RekhaShah
Comment Utility
"..but I don't work on weekends! :-) "
Lucky you!!

 I am very thankful to  you. Like I mentioned earlier, it is a very complex project  with lots of objects. Is  there a reason, why each object should be embedded in its on project? This is a desktop app with .mdb file. Sure, I am looking for scalability,  but does it have  to be composed of so many dlls?
0
 
LVL 7

Expert Comment

by:klakkas
Comment Utility
If you want to "simplify" it, you could merge DAL, BLL and ObjectDefinition in one DLL project and the Windows Forms App in a different project. Of course, both projects will be under the same solution. Just remember that only the BLL and ObjDef classes will be public, the DAL will be private.

I insist on the DLL, because if you want to create a WebSite for this work, alll you will have to do is add this DLL to the WebSite project (no source code).

0
 

Author Comment

by:RekhaShah
Comment Utility
I got it (I think) .. thanks. So I will have the following in my Solution:

dll for each of my objects - customer, product,category etc with its properties  . I will reference them in my solution

a BLL  project with separate class for each object e.g.  BLL_customer.cls, BLL_Products.cls etc

A DA Project with all the classes for each objects with getters and setters .e.g. DA_Products.cls, DA_Category.cls and so  on.

And the easiest layer :PL with all my forms ( I am looking into WPF also).

Am I in the right direction?


0
 
LVL 7

Expert Comment

by:klakkas
Comment Utility
No, no, you missunderstood me!

1 single ObjDef.dll with ALL the objects Definition. Each object is a different class file in the project.

1 DAL.dll which has reference to ObjDef.dll and uses these classes to return data.

1 BLL.dll which has reference to ObjDef.dll and DAL.dll and uses the objDef classes to return data.

1 windows forms application, which has reference to BLL.dll. I am not if you also must reference ObjDef.dll in your .exe project.

A total of 1 exe and 3 dll files.
0
 

Author Comment

by:RekhaShah
Comment Utility
I finally got it!  Dhu...
Yes, I was wondering about having separate dll for each object :(
Thank you very much for clarifying.

I am on my way to OOP!
0

Featured Post

Get up to 2TB FREE CLOUD per backup license!

An exclusive Black Friday offer just for Expert Exchange audience! Buy any of our top-rated backup solutions & get up to 2TB free cloud per system! Perform local & cloud backup in the same step, and restore instantly—anytime, anywhere. Grab this deal now before it disappears!

Join & Write a Comment

Experts-Exchange is a great place to come for help with solutions for your database issues, and many problems are resolved within minutes of being posted.  Others take a little more time and effort and often providing a sample database is very helpf…
A simple tool to export all objects of two Access files as text and compare it with Meld, a free diff tool.
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Basics of query design. Shows you how to construct a simple query by adding tables, perform joins, defining output columns, perform sorting, and apply criteria.

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now