Link to home
Start Free TrialLog in
Avatar of AWestEng
AWestEngFlag for Sweden

asked on

Namespace/Class structure

Hi!

Need some help to create a Namespace/Class structure.

I have a Namespace that is called SQLHandler in this I'm going to place
Class MySQLDotNet
Class MsAccess
Class MsSQL

That part is ok.

The problem comes when I need to devide all the functions to a specific class

for example. If I need to add BLOB functions I like to put all function for BLOB's in there own class

Now to the question,

What is the best appraoch to make a nice structure of this.

1: Should I put the BLOB class into the MySQLDotNet class
2: Seperate them, and import a interface into the MySQLDotNet class so it can talk to BLOB class
3: Or just place all functions under the MySQLDotNet class (this will be about 4000 rows of code in one file)
4: other

I have several classes, BLOB, AlterDatabase, ExecuteQuerys, Optimize and so on, and all of them I need to "connect" to the MySQLDotNet class in some way.
Avatar of jacek_j1978
jacek_j1978
Flag of Poland image

Hi,
I think the best way would be to derive from the BLOB Class, but it would be easier to answer when you show the code.
Avatar of AWestEng

ASKER

multi inherits is not possible in vb.net
Hi AW

Some days ago you asked something similar

Regarding interface versus inheritance

A rule of thumb (my 2 cent opinion)

1) When you can define an   is-a relationship between the classes , then inheritance should be the choise.
2) When you can define an   has-a relationship between the classes , then interface should be the choise.

when modeling a relationship where the lower level objects might differ quite a bit in methods and properties
then you should use inheritance

when the lower level objects allmost will have the same methods , but the implementation of these methods will
differ in some way then its recommended to use interface's

So this is the answer to your question.


I know this is written in C# but the article is very important concept when you are deriving and using inheritance"

http://www.ankermoerk.dk/Kurser/DMU-Arkitektur-Foraar08/Notes/lsp.pdf

Also quote
<Or just place all functions under the MySQLDotNet class (this will be about 4000 rows of code in one file)

This is a violation of the OOP principles (class responcebillity)


And at last have you had a look at Enterprise Library 3.1

http://msdn.microsoft.com/en-us/library/aa480458.aspx
which is database independant (oracle,mysql,mssql,etc...)

Enterprise Library 3.1 - May 2007

http://www.microsoft.com/downloads/details.aspx?familyid=4c557c63-708f-4280-8f0c-637481c31718&displaylang=en&hash=8Rg9btijp8AMqEzTC1TETKbR3W9RtBzaFHefUpMNBGvsxNOxao80DSPzsdJ69ei%2bO3MLEAVxhr5ClZvdXr3ptQ%3d%3d


it prevents you from enventing the wheel again

vbturbo
here is the database class
 
'===============================================================================
' Microsoft patterns & practices Enterprise Library
' Data Access Application Block QuickStart
'===============================================================================
' Copyright © Microsoft Corporation.  All rights reserved.
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
' OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
' LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
' FITNESS FOR A PARTICULAR PURPOSE.
'===============================================================================
 
 
' Encapulsates access to the database.
Public Class SalesData
 
    Public Sub SalesData()
    End Sub
 
 
    ' Retrieves a list of customers from the database.
    ' Returns: List of customers in a string.
    ' Remarks: Demonstrates retrieving multiple rows of data using
    ' a DataReader
    Public Function GetCustomerList() As String
 
        ' DataReader that will hold the returned results            
        ' Create the Database object, using the default database service. The
        ' default database service is determined through configuration.
        Dim db As Database = DatabaseFactory.CreateDatabase()
 
        Dim sqlCommand As String = "Select CustomerID, Name, Address, City, Country, PostalCode " & _
            "From Customers"
        Dim dbCommand As DbCommand = db.GetSqlStringCommand(sqlCommand)
 
        Dim readerData As StringBuilder = New StringBuilder
 
        ' The ExecuteReader call will request the connection to be closed upon
        ' the closing of the DataReader. The DataReader will be closed 
        ' automatically when it is disposed.
        Using dataReader As IDataReader = db.ExecuteReader(dbCommand)
 
            ' Iterate through DataReader and put results to the text box.
            ' DataReaders cannot be bound to Windows Form controls (e.g. the
            ' resultsDataGrid), but may be bound to Web Form controls.
            While (dataReader.Read())
                ' Get the value of the 'Name' column in the DataReader
                readerData.Append(dataReader("Name"))
                readerData.Append(Environment.NewLine)
            End While
        End Using
        Return readerData.ToString()
    End Function
 
    ' Retreives all products in the specified category.
    ' Category: The category containing the products.
    ' Returns: DataSet containing the products.
    ' Remarks: Demonstrates retrieving multiple rows using a DataSet.
    Public Function GetProductsInCategory(ByRef Category As Integer) As DataSet
 
        ' Create the Database object, using the default database service. The
        ' default database service is determined through configuration.
        Dim db As Database = DatabaseFactory.CreateDatabase()
 
        Dim sqlCommand As String = "GetProductsByCategory"
        Dim dbCommand As DbCommand = db.GetStoredProcCommand(sqlCommand)
 
        ' Retrieve products from the specified category.
        db.AddInParameter(dbCommand, "CategoryID", DbType.Int32, Category)
 
        ' DataSet that will hold the returned results            
        Dim productsDataSet As DataSet = Nothing
 
        productsDataSet = db.ExecuteDataSet(dbCommand)
 
        ' Note: connection was closed by ExecuteDataSet method call 
 
        Return productsDataSet
    End Function
 
    ' Updates the product database.
    ' Returns: The number of rows affected by the update.
    ' Remarks: Demonstrates updating a database using a DataSet.
    Public Function UpdateProducts() As Integer
        ' Create the Database object, using the default database service. The
        ' default database service is determined through configuration.
        Dim db As Database = DatabaseFactory.CreateDatabase()
 
        Dim productsDataSet As DataSet = New DataSet
 
        Dim sqlCommand As String = "Select ProductID, ProductName, CategoryID, UnitPrice, LastUpdate " & _
            "From Products"
        Dim dbCommand As DbCommand = db.GetSqlStringCommand(sqlCommand)
 
        Dim productsTable As String = "Products"
 
        ' Retrieve the initial data
        db.LoadDataSet(dbCommand, productsDataSet, productsTable)
 
        ' Get the table that will be modified
        Dim table As DataTable = productsDataSet.Tables(productsTable)
 
        ' Add a new product to existing DataSet
        Dim addedRow As DataRow = table.Rows.Add(New Object() {DBNull.Value, "New product", 11, 25})
 
        ' Modify an existing product
        table.Rows(0)("ProductName") = "Modified product"
 
        ' Establish our Insert, Delete, and Update commands
        Dim insertCommand As DbCommand = db.GetStoredProcCommand("AddProduct")
        db.AddInParameter(insertCommand, "ProductName", DbType.String, "ProductName", DataRowVersion.Current)
        db.AddInParameter(insertCommand, "CategoryID", DbType.Int32, "CategoryID", DataRowVersion.Current)
        db.AddInParameter(insertCommand, "UnitPrice", DbType.Currency, "UnitPrice", DataRowVersion.Current)
 
        Dim deleteCommand As DbCommand = db.GetStoredProcCommand("DeleteProduct")
        db.AddInParameter(deleteCommand, "ProductID", DbType.Int32, "ProductID", DataRowVersion.Current)
 
        Dim updateCommand As DbCommand = db.GetStoredProcCommand("UpdateProduct")
        db.AddInParameter(updateCommand, "ProductID", DbType.Int32, "ProductID", DataRowVersion.Current)
        db.AddInParameter(updateCommand, "ProductName", DbType.String, "ProductName", DataRowVersion.Current)
        db.AddInParameter(updateCommand, "LastUpdate", DbType.DateTime, "LastUpdate", DataRowVersion.Current)
 
        ' Submit the DataSet, capturing the number of rows that were affected
        Dim rowsAffected As Integer = db.UpdateDataSet(productsDataSet, "Products", insertCommand, updateCommand, deleteCommand, UpdateBehavior.Standard)
 
        Return rowsAffected
 
    End Function
 
    ' Retrieves details about the specified product.
    ' productID: The ID of the product used to retrieve details.
    ' Returns: The product details as a string.
    ' Remarks: Demonstrates retrieving a single row of data using output parameters.
    Public Function GetProductDetails(ByRef productID As Integer) As String
 
        ' Create the Database object, using the default database service. The
        ' default database service is determined through configuration.
        Dim db As Database = DatabaseFactory.CreateDatabase()
 
        Dim sqlCommand As String = "GetProductDetails"
        Dim dbCommand As DbCommand = db.GetStoredProcCommand(sqlCommand)
 
        ' Add paramters
        ' Input parameters can specify the input value
        db.AddInParameter(dbCommand, "ProductID", DbType.Int32, productID)
        ' Output parameters specify the size of the return data
        db.AddOutParameter(dbCommand, "ProductName", DbType.String, 50)
        db.AddOutParameter(dbCommand, "UnitPrice", DbType.Currency, 8)
 
        db.ExecuteNonQuery(dbCommand)
 
        ' Row of data is captured via output parameters
        Dim results As String = String.Format(CultureInfo.CurrentCulture, "{0}, {1}, {2:C} ", _
                                       db.GetParameterValue(dbCommand, "ProductID"), _
                                       db.GetParameterValue(dbCommand, "ProductName"), _
                                       db.GetParameterValue(dbCommand, "UnitPrice"))
 
        Return results
    End Function
 
    ' Retrieves the specified product's name.
    ' productID: The ID of the product.
    ' Returns: The name of the product.
    ' Remarks: Demonstrates retrieving a single item. Parameter discovery
    ' is used for determining the properties of the productID parameter.
    Public Function GetProductName(ByRef productID As Integer) As String
 
        ' Create the Database object, using the default database service. The
        ' default database service is determined through configuration.
        Dim db As Database = DatabaseFactory.CreateDatabase()
 
        ' Passing the productID value to the GetStoredProcCommand
        ' results in parameter discovery being used to correctly establish the parameter
        ' information for the productID. Subsequent calls to this method will
        ' cause the block to retrieve the parameter information from the 
        ' cache, and not require rediscovery.
        Dim sqlCommand As String = "GetProductName"
        Dim dbCommand As DbCommand = db.GetStoredProcCommand(sqlCommand, productID)
 
        ' Retrieve ProductName. ExecuteScalar returns an object, so
        ' we cast to the correct type (string).
        Dim productName As String = Convert.ToString(db.ExecuteScalar(dbCommand))
 
        Return productName
    End Function
 
    ' Retrieves a list of products.
    ' Returns: A list of products as an XML string.
    ' Remarks: Demonstrates retrieving multiple rows of data as XML. This
    ' method is not portable across database providers, but is 
    ' specific to the SqlDatabase.
    Public Function GetProductList() As String
 
        ' Use a named database instance that refers to a SQL Server database.
        Dim dbSQL As SqlDatabase = DirectCast(DatabaseFactory.CreateDatabase(), SqlDatabase)
 
        ' Use "FOR XML AUTO" to have SQL return XML data
        Dim sqlCommand As String = "Select ProductID, ProductName, CategoryID, UnitPrice, LastUpdate " & _
            "From Products FOR XML AUTO"
 
        Dim dbCommand As DbCommand = dbSQL.GetSqlStringCommand(sqlCommand)
 
        Dim productsReader As XmlReader = Nothing
        Dim productList As StringBuilder = New StringBuilder
 
        Try
            productsReader = dbSQL.ExecuteXmlReader(dbCommand)
 
            ' Iterate through the XmlReader and put the data into our results.
            While (Not productsReader.EOF)
 
                If (productsReader.IsStartElement()) Then
                    productList.Append(productsReader.ReadOuterXml())
                    productList.Append(Environment.NewLine)
                End If
            End While
        Finally
            ' Close the Reader.
            If (Not productsReader Is Nothing) Then
                productsReader.Close()
            End If
 
            ' Explicitly close the connection. The connection is not closed
            ' when the XmlReader is closed.
            If (Not dbCommand.Connection Is Nothing) Then
                dbCommand.Connection.Close()
            End If
        End Try
        Return productList.ToString()
    End Function
 
    ' Transfers an amount between two accounts.
    ' transactionAmount: Amount to transfer.
    ' sourceAccount: Account to be credited.
    ' destinationAccount: Account to be debited.
    ' Returns: true if sucessful otherwise false.
    ' Remarks: Demonstrates executing multiple updates within the 
    ' context of a transaction.
    Public Function Transfer(ByRef transactionAmount As Integer, ByRef sourceAccount As Integer, ByRef destinationAccount As Integer) As Boolean
 
        Dim result As Boolean = False
 
        ' Create the Database object, using the default database service. The
        ' default database service is determined through configuration.
        Dim db As Database = DatabaseFactory.CreateDatabase()
 
        ' Two operations, one to credit an account, and one to debit another
        ' account.
        Dim sqlCommand As String = "CreditAccount"
        Dim creditCommand As DbCommand = db.GetStoredProcCommand(sqlCommand)
 
        db.AddInParameter(creditCommand, "AccountID", DbType.Int32, sourceAccount)
        db.AddInParameter(creditCommand, "Amount", DbType.Int32, transactionAmount)
 
        sqlCommand = "DebitAccount"
        Dim debitCommand As DbCommand = db.GetStoredProcCommand(sqlCommand)
        db.AddInParameter(debitCommand, "AccountID", DbType.Int32, destinationAccount)
        db.AddInParameter(debitCommand, "Amount", DbType.Int32, transactionAmount)
 
        Using connection As DbConnection = db.CreateConnection()
            connection.Open()
            Dim transaction As DbTransaction = connection.BeginTransaction()
 
            Try
 
                ' Credit the first account
                db.ExecuteNonQuery(creditCommand, transaction)
                ' Debit the second account
                db.ExecuteNonQuery(debitCommand, transaction)
                ' Commit the transaction
                transaction.Commit()
 
                result = True
            Catch
                ' Rollback transaction 
                transaction.Rollback()
            End Try
 
            connection.Close()
            Return result
        End Using
    End Function
End Class

Open in new window

Oki, I'm nor sure that I'm with you to 100%.

What I have is 3 diffrent classes that handle 3 different types of databases.
class MySQL
Class MsAccess
Class MsSQL
They are all part of the Namesapce SQLHandler.

Now to the problem.

For example:
Each class has a few functions that are realted to ExecuteNonQuery functions.  
I also have some functions that are related to BLOB's and I have functions that are related to "Alter the database"
and so on....

The ExecuteNonQuery are not the same for the diffrent databases, so I have x number of function for each database class.

So this is what I have..

Public Class MySQL
 ...... Functions
 ...... Prop

        Public Class NonQuerys
               ---- Functions
        End Class

         Public Class BLOB
               ---- Functions
        End Class
End Class


Public Class MsAccess
 ...... Functions
 ...... Prop

        Public Class NonQuerys
               ---- Functions
        End Class
End Class


Is this a good solution.??  The classes NonQuerys are not the same in MySQL and MsAccess, so they are two complete different classes with complete different function structures.

What I like to do is is to sperate the NonQuerys Class and BLOB Calss from MySQL and call them NonQuerysMySQL and  BLOBMySQL and then in some way communicate with them

Why I use the sub classes is because there are so many functions and it's easier to do this

Dim mm as New SQLHandler.MySQL(ConnectionString)

mm. NonQyerys.InsertDataset(ds)

Then you don't need to set the name Nonquery in the function name and it's easier to find the correct function you need.

So I want this
Namespace SQLHandler
Public Class MySQL
 ...... Functions
 ...... Prop
End Class
        Public Class MySQLNonQuerys
               Sub InsertDataset(ds as dataset)
                 -------------
               End Sub
        End Class
         Public Class MySQLBLOB
               ---- Functions
        End Class
End Namespace

And still can do this..
Dim mm as New SQLHandler.MySQL(ConnectionString)
mm. MySQLBLOB. InsertDataset (ds)

So is this possible to have this with some kind of modify structure of the code above

Why? Because I want files with as little code as possible and I still want the structure so its easy to group functions to their belonging.
Try consider implementing Polymorphism via Interface


in your form load event have this

TestDatabaseActions.Test()

vbturbo
Imports System.Data.OleDb
 
Public Module TestDatabaseActions
 
 
    Public Sub Test()
        '//test picturebox
        Dim pb As New PictureBox
 
 
        Dim dbType(2) As IDatabase
        dbType(0) = New MySQL("MySqlProvider connectionstring")
        dbType(1) = New MsAccess("OleDbProvider connectionstring")
 
 
        dbType(0).BLOB("sql", "myFieldName", pb)
        dbType(0).ExecuteNonQuery("sql")
 
 
        dbType(1).BLOB("sql", "myFieldName", pb)
        dbType(1).ExecuteNonQuery("sql")
 
    End Sub
End Module
 
 
Public Interface IDatabase
 
    ReadOnly Property M_con() As String
    Function BLOB(ByVal sSql As String, ByVal FieldName As String, ByVal PictureBox As PictureBox) As Integer
    Sub ExecuteNonQuery(ByVal sSql As String)
 
 
End Interface
 
 
 
Public Class MySQL
    Implements IDatabase
 
 
    Private m_con As String
 
    Sub New(ByVal setConStr As String)
        m_con = setConStr
    End Sub
 
    Private ReadOnly Property ConnectionString() As String Implements IDatabase.M_con
        Get
            Return m_con
        End Get
    End Property
 
    Public Function MySQLInsertImageToBLOB(ByVal sSql As String, ByVal FieldName As String, ByVal PictureBox As PictureBox) As Integer Implements IDatabase.BLOB
        '// Do stuff
        Return MessageBox.Show("MySql Blob ops done")
    End Function
    Public Sub ExecuteNonQuery(ByVal sSql As String) Implements IDatabase.ExecuteNonQuery
        Dim m_cn As New OleDb.OleDbConnection
        '// PURPOSE: This function will execute a non-query SQL statement such
        '// as an INSERT or UPDATE or DELETE statement.
        If m_cn.State <> ConnectionState.Open Then m_cn.Open()
        Try
 
            Dim cmd As OleDbCommand = m_cn.CreateCommand()
            cmd.CommandText = sSql
            cmd.ExecuteNonQuery()
        Catch ex As Exception
            MsgBox(ex.Message, MsgBoxStyle.Critical)
        Finally
            m_cn.Close()
        End Try
 
    End Sub
End Class
 
 
 
Public Class MsAccess : Implements IDatabase
 
 
    Private m_con As String
 
    Sub New(ByVal setConStr As String)
        m_con = setConStr
    End Sub
 
    Private ReadOnly Property ConnectionString() As String Implements IDatabase.M_con
        Get
            Return m_con
        End Get
    End Property
 
    Public Function MsAccessBLOB(ByVal sSql As String, ByVal FieldName As String, ByVal PictureBox As PictureBox) As Integer Implements IDatabase.BLOB
        '// Do stuff
        Return MessageBox.Show("MsAccess Blob ops done")
    End Function
 
    Public Sub ExecuteNonQuery(ByVal sSql As String) Implements IDatabase.ExecuteNonQuery
        Dim m_cn As New OleDb.OleDbConnection
        '// PURPOSE: This function will execute a non-query SQL statement such
        '// as an INSERT or UPDATE or DELETE statement.
        If m_cn.State <> ConnectionState.Open Then m_cn.Open()
        Try
 
            Dim cmd As OleDbCommand = m_cn.CreateCommand()
            cmd.CommandText = sSql
            cmd.ExecuteNonQuery()
        Catch ex As Exception
            MsgBox(ex.Message, MsgBoxStyle.Critical)
        Finally
            m_cn.Close()
        End Try
 
    End Sub
End Class

Open in new window

here you my have something...

but is it possible to spilt up the classes even more..

I like to do this
  dbType(0).BLOB.Insert("sql", "myFieldName", pb)
dbType(0).BLOB.Get("sql", "myFieldName")
 dbType(0).ExecuteNonQuery.Insert("sql")
dbType(0).ExecuteNonQuery.Select("sql")
dbType(0).ExecuteNonQuery.Delete("sql")

Why? because I have something like 10 diffrent types of BLOB functions and I like to have them in a seperated files/class and of course the same for NonQuerys and so on.






ASKER CERTIFIED SOLUTION
Avatar of vbturbo
vbturbo
Flag of Denmark image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
That is what I want :)

But how do I do this with code?
How do I code that structure you showing?

can UModel generate that code?