AWestEng
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.
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.
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
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
ASKER
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(Connectio nString)
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(Connectio nString)
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.
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(Connectio
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(Connectio
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
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
ASKER
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("sq l")
dbType(0).ExecuteNonQuery. Select("sq l")
dbType(0).ExecuteNonQuery. Delete("sq l")
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.
but is it possible to spilt up the classes even more..
I like to do this
dbType(0).BLOB.Insert("sql
dbType(0).BLOB.Get("sql", "myFieldName")
dbType(0).ExecuteNonQuery.
dbType(0).ExecuteNonQuery.
dbType(0).ExecuteNonQuery.
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
That is what I want :)
But how do I do this with code?
But how do I do this with code?
ASKER
How do I code that structure you showing?
can UModel generate that code?
can UModel generate that code?
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.