Assigning appSettings values to a String - vb.net

I am getting an error. I am trying to connect to SQL SERVER with this appSettings. But this fragment of code is giving an error.
Warning 6 'Public Shared ReadOnly Property AppSettings As System.Collections.Specialized.NameValueCollection' is obsolete: 'This method is obsolete, it has been replaced by System.Configuration!System.Configuration.ConfigurationManager.AppSettings'.
`
Public Class clsDL
'Fields - Data
Private adp As SqlDataAdapter
Private cmd As SqlCommand
Private Cn As SqlConnection
Private Shared db As clsDL
Private dr As SqlDataReader
Private ds As DataSet
Private dt As DataTable
Private gUserPwdSeed As Object = 10
Private intIndex As Integer
Private m_trans As SqlTransaction
Private objConSettings As ConfigurationSettings
Private strCnString As String
Private strDatabase As String
Private strPwd As String
Private strServer As String
Private strUID As String
Private Sub Connect()
Try
Me.strServer = ConfigurationSettings.AppSettings("Server")
Me.strDatabase = ConfigurationSettings.AppSettings("Database")
Me.strUID = ConfigurationSettings.AppSettings("UID")
End Sub`

Use the suggestion in the warning.
Private Sub Connect()
Try
Me.strServer = System.Configuration.ConfigurationManager.AppSettings("Server")
Me.strDatabase = System.Configuration.ConfigurationManager.AppSettings("Database")
Me.strUID = System.Configuration.ConfigurationManager.AppSettings("UID")
End Sub`
We took that simple approach from our old codebase whilst converting up rather than rewriting and it worked fine.

Related

How do you dispose a local SqlConnection?

Im programming in vb.net
I want to read data from an mssql database. I want to make it flexible for several different queries, so I put the connecting part into a separate class. Whenever I want to make a query I can get with it a preconfigured DataAdapter.
But because of this separation I dont know how to correctly dispose my SqlConnection after collecting the data.
An examplatory use:
Public Class Form1
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim DBA As New DBAccess("dummycommand")
DBA.provideAdapter.Fill(dummytable)
...Dispose? 'This is the part where you usually dispose your datacollecting ressources
End Sub
End Class
Friend Class DBAccess
Private SqlString As String
Friend Sub New(ByVal sql As String)
SqlString = sql
End Sub
Friend Function provideAdapter() As SqlDataAdapter
Dim cn As New SqlConnection("dummyconstring")
Dim da As New SqlDataAdapter(SqlString, cn)
Return da
End Function
End Class
Can you tell me how I change this concept to fit a dispose?
You could make your data access class Disposable
Friend Class DBAccess
Implements IDisposable
Private ReadOnly sqlString As String
Private disposedValue As Boolean
Private cn As SqlConnection
Private da As SqlDataAdapter
Friend Sub New(sql As String)
sqlString = sql
End Sub
Friend Function provideAdapter() As SqlDataAdapter
cn = If(cn, New SqlConnection("dummyconstring"))
da = If(da, New SqlDataAdapter(SqlString, cn))
Return da
End Function
Protected Overridable Sub Dispose(disposing As Boolean)
If Not disposedValue Then
If disposing Then
da?.Dispose()
cn?.Dispose()
End If
disposedValue = True
End If
End Sub
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(disposing:=True)
GC.SuppressFinalize(Me)
End Sub
End Class
and use it like this
Using DBA As New DBAccess("dummycommand")
DBA.provideAdapter.Fill(dummytable)
End Using ' Will automatically call Dispose here
but in the long run you could look at an ORM such as Entity Framework to make your life easier.

Populate class from query on VB Net

Help translate C# code from this link Simplest way to populate class from query in C# to VB Net.
Option Infer On
Imports System.Reflection
Private Sub Main()
Dim connectionString = "..."
Dim records = (New Query(connectionString)).SqlQuery(Of TVChannel)("select top 10 * from TVChannel")
End Sub
Private Class TVChannel
Public Property number() As String
Public Property title() As String
Public Property favoriteChannel() As String
Public Property description() As String
Public Property packageid() As String
Public Property format() As String
End Class
Public Class Query
Private ReadOnly _connectionString As String
Public Sub New(ByVal connectionString As String)
_connectionString = connectionString
End Sub
Public Function SqlQuery(Of T)(ByVal query As String) As List(Of T)
Dim result = New List(Of T)()
Using connection = New SqlConnection(_connectionString)
connection.Open()
Using command = connection.CreateCommand()
command.CommandText = query
Using reader = command.ExecuteReader()
Dim columns = Enumerable.Range(0, reader.FieldCount).Select(Function(f) reader.GetName(f)).ToArray()
Dim properties = GetType(T).GetProperties()
Do While reader.Read()
Dim data = New Object(reader.FieldCount - 1){}
reader.GetValues(data)
Dim instance = DirectCast(Activator.CreateInstance(GetType(T)), T)
For i = 0 To data.Length - 1
If data(i) Is DBNull.Value Then
data(i) = Nothing
End If
Dim [property] = properties.SingleOrDefault(Function(x) x.Name.Equals(columns(i), StringComparison.InvariantCultureIgnoreCase))
If [property] IsNot Nothing Then
[property].SetValue(instance, Convert.ChangeType(data(i), [property].PropertyType))
End If
Next i
result.Add(instance)
Loop
End Using
End Using
End Using
Return result
End Function
End Class
but, I got error on this line
Dim instance = DirectCast(Activator.CreateInstance(GetType(T)), T)
System.MissingMethodException: 'No parameterless constructor defined for this object.'
This is a much better pattern to follow. It addresses at least four issues in the original code (sql injection, Nothing vs null, constructor access, unnecessary allocations):
Public Module SQL
Private ReadOnly _connectionString As String = "..."
Public Iterator Function Query(Of T)(ByVal query As String, translate As Func(IDataRecord, T), ParamArray data() As SqlParameter) As IEnumerable(Of T)
Using connection As New SqlConnection(_connectionString), _
command As New SqlCommand(query, connection)
If data IsNot Nothing Then command.Parameters.AddRange(data)
connection.Open()
Using reader As SqlDataReader = command.ExecuteReader()
While reader.Read()
Yield translate(reader)
End While
reader.Close()
End Using
End Using
End Function
End Module
Call it like this:
Private Sub Main()
Dim records = SQL.Query("select top 10 * from TVChannel",
Function(r)
'Yes, you're doing the mapping manually now for each query.
'But this lets you properly account for things NULL, column name mismatches, computed properties, etc.
Return New TVChannel With {
.number = r["number"],
.title = r["title"],
.favoriteChannel = r["favoriteChannel"],
.description = r["description"],
.packageid = r["packageid"],
.format = r["format"]
}
End Function,
Nothing)
For Each channel As TVChannel In records
Console.WriteLine($"Channel {channel.number}, {channel.title}")
Next
End Sub

VB.NET connection to MySQL Add Model

I'm very new to .NET. I am trying to use a code example from the first person that posted a response, here: Connect to remote MySQL database using VB.NET 2010
I would like to instantiate the MySqlVB model object but when I add the following code into the controller, I get a not found error. I don't know how to resolve this.
The error is: Warning 1 Namespace or type specified in the Imports 'MySql.Data.MySqlClient' doesn't contain any public member or cannot be found. Make sure the namespace or the type is defined and contains at least one public member. Make sure the imported element name doesn't use any aliases.
What I need is to run a MySQL query and to return the dataset to the controller. Can someone show me how to do this, please?
I'm using VB 2010 Express to do this.
This is the controller
Public Class Form1
Private Sub PrintBtn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PrintBtn.Click
Dim data As New MySqlVB
With data
If .Connection Then
MessageBox.Show("Database Conneted.")
Else
MessageBox.Show(.ErrorMessage)
End If
End With
End Sub
End Class
And this is my model object
Imports MySql.Data.MySqlClient
Public Class MySqlVB
Private _connection As New MySqlConnection
Private _errormessge As String
Private _servername As String = "xxx.xxx.xxx.xxx"
Private _databasename As String = "testdb"
Private _userid As String = "theuser"
Private _password As String = "thepass"
Public WriteOnly Property ServerName() As String
Set(ByVal value As String)
_servername = value
End Set
End Property
Public WriteOnly Property DatabaseName() As String
Set(ByVal value As String)
_databasename = value
End Set
End Property
Public WriteOnly Property UserID() As String
Set(ByVal value As String)
_userid = value
End Set
End Property
Public WriteOnly Property Password() As String
Set(ByVal value As String)
_password = value
End Set
End Property
Public ReadOnly Property ErrorMessage() As String
Get
Return _errormessge
End Get
End Property
Public Function Connection() As Boolean
Try
_connection.ConnectionString = "Server=" & _servername & ";Port=3306;Database=" & _databasename & ";User ID=" & _userid & ";Password=" & _password & ""
_connection.Open()
If _connection.State = ConnectionState.Open Then
_connection.Close()
Return True
End If
Catch ex As Exception
_errormessge = ex.Message
Return False
End Try
End Function
End Class
Assuming you have fixed your reference to MySql.Data.MySqlClient I think your class could use some work.
Public Class DataAccess
Private ConnectionString As String
Public Sub New(UserName As String, Password As String)
Dim builder As New MySqlConnectionStringBuilder With {
.Server = "xxx.xxx.xxx.xxx",
.Database = "testdb",
.UserID = UserName,
.Password = Password
}
ConnectionString = builder.ConnectionString
Debug.Print(ConnectionString) 'just to see what the builder created
End Sub
Public Function TestConnecion() As Boolean
Using cn As New MySqlConnection(ConnectionString)
Try
cn.Open()
Catch ex As Exception
Debug.Print(ex.Message) 'just to see what is wrong with connection
Return False
End Try
End Using
Return True
End Function
Public Function GetData() As DataTable
Dim dt As New DataTable
Using cn As New MySqlConnection(ConnectionString)
Using cmd As New MySqlCommand("Select * From SomeTable")
cn.Open()
dt.Load(cmd.ExecuteReader)
End Using
End Using
Return dt
End Function
End Class
Assuming you have a DataGridView to display data and 2 text boxes for user id and password, you can use your class in your form like this.
Private Sub FillGrid()
Dim daClass As New DataAccess(txtUser.Text, txtPassword.Text)
Dim dt = daClass.GetData
DataGridView1.DataSource = dt
End Sub
Of course you will need to add error handling. Also you need to salt and hash passwords. Plain text passwords should never be stored.

Setting database class at run time in VB.Net

I have the follow classes for Sqlite and SqlServer:
Class for SQLite:
Imports System.Data.SQLite
Public Class clsOperDB_SQLite
Public Shared Function getValue(sql As String) As String
Try
Using conn As New SQLiteConnection(strConn_SQLITE)
Using cmd As New SQLiteCommand()
cmd.Connection = conn
conn.Open()
cmd.CommandText = sql
Return cmd.ExecuteScalar
End Using
End Using
Catch ex As Exception
MsgBox(ex.Message)
End Try
Return ""
End Function
End Class
Class for SQLSERVER:
Imports System.Data.SqlClient
Public Class clsOperDB_SQLSERVER
Public Shared Function getValue(sql As String) As String
Try
Using conn As New SqlConnection(strConn_SQLSERVER)
Using cmd As New SqlCommand()
cmd.Connection = conn
conn.Open()
cmd.CommandText = sql
Return cmd.ExecuteScalar
End Using
End Using
Catch ex As Exception
MsgBox(ex.Message)
End Try
Return ""
End Function
End Class
this is my test form:
Public Class Form1
'form level variable
Dim dbConnector
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim connectionType As String = "SQLITE"
' need something like this or any way to set form level variable
If connectionType = "SQLITE" Then
dbConnector = clsOperDB_SQLite
Else
dbConnector = clsOperDB_SQLSERVER
End If
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'get value from SQLITE
Dim ValueFromDatabase As String = dbConnector.getValue("select .....")
End Sub
End Class
I need help to define dbConnector variable and set its value, also intellisense should show me class methods, using a parameter I want to change database and avoid using a conditional for every time I want to use one or the other database :
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim Query As String = "Select ..."
Dim ValueFromDatabase As String = ""
' dont want to use if for each sql query
If connectionType = "SQLITE" Then
ValueFromDatabase = clsOperDB_SQLite.getValue(Query)
Else
ValueFromDatabase = clsOperDB_SQLSERVER.getValue(Query)
End If
End Sub
The rest of methods and params for both classes are the same only change class data objects (SQLiteConnection, SqlConnection, and so)
Thanks
You should define an interface that species all the common members. You can then create a class for each data source that implements that interface. In your application code, you can then declare a variable of that interface type and assign an instance of any class that implements it to that variable. You can then just use that variable and invoke any member of the interface without caring what type the actual class instance is.
The interface and the implementing classes would look something like this:
Public Interface IDataAccessProvider
Function GetValue(sql As String) As String
End Interface
Public Class SqliteDataAccessProvider
Implements IDataAccessProvider
Public Function GetValue(sql As String) As String Implements IDataAccessProvider.GetValue
'Provide SQLite-specific implementation here.
End Function
End Class
Public Class SqlServerDataAccessProvider
Implements IDataAccessProvider
Public Function GetValue(sql As String) As String Implements IDataAccessProvider.GetValue
'Provide SQL Server-specific implementation here.
End Function
End Class
Your application code might then look like this:
Private dataAccessProvider As IDataAccessProvider
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'Read a value that identifies the data source and store it here.
'The value might be stored in the config file or wherever else is appropriate.
Dim dataSourceIdentifier As String
Select Case dataSourceIdentifier
Case "SQLite"
dataAccessProvider = New SqliteDataAccessProvider()
Case "SQL Server"
dataAccessProvider = New SqlServerDataAccessProvider()
End Select
End Sub
You can then just call dataAccessProvider.GetValue in your code without any care for what the data source actually is, except to ensure that your SQL syntax is valid for that data source.
Please note that, while what you do is up to you, I have chosen to use a sane naming convention in this code. No one would last long working for me using class names like clsOperDB_SQLSERVER. There's a reason you don't see any types with names like that in the .NET Framework.

Set SqlParameter in VB.NET?

I'm new with classes and I want to create a SqlCommandManager class and I can't figure out how to pass SqlParameter on my class.
For example if I want to insert data I would just use my class like client below.
'Client
Dim m_SqlComManager as new SQLCommandManager("MyConnectionString")
m_SqlCommandManager.Commandtext = "INSERT INTO [TableName]([Field1],[Field2])VALUES(#Field1,Field2);"
m_SqlCommandManager.Parameters.AddWithValue("#Field1","SomeValue1")
m_SqlCommandManager.Parameters.AddWithValue("#Field2","SomeValue2")
m_SqlCommandManager.ExecuteNonQuery()
'Here is my class
Imports System.Data.SqlClient
Public Class SQLCommandManager
Private m_SqlParameters As SqlParameter()
Private m_Commandtext As String
Private m_ConStr As String
Public WriteOnly Property SQlParameter() As SqlParameter()
Set(ByVal value As SqlParameter())
value = m_SqlParameters
End Set
End Property
Public Property CommandText() As String
Get
Return m_Commandtext
End Get
Set(ByVal value As String)
value = m_Commandtext
End Set
End Property
Public Sub New(ByVal con As String)
m_ConStr = con
End Sub
Public Sub ExecuteNonQuery()
Using con As New SqlConnection(m_ConStr)
Using com As New SqlCommand
com.Connection = con
com.CommandText = m_Commandtext
'Please help
'How can i insert parameter here from client..
If con.State = ConnectionState.Closed Then
con.Open()
End If
com.ExecuteNonQuery()
End Using
End Using
End Sub
End Class
How how can I set the parameters before the ExecuteNonQuery method?
Thanks in advance..
I would do something like this:
Public Class SqlCommandManager
Private m_SqlParameters As List(Of SqlParameter)
Private m_Commandtext As String
Private m_ConStr As String
Public Sub New()
m_SqlParameters = New List(Of SqlParameter)()
End Sub
Public ReadOnly Property SqlParameters() As List(Of SqlParameter)
Get
Return m_SqlParameters
End Get
End Property
Public Property CommandText() As String
Get
Return m_Commandtext
End Get
Set
value = m_Commandtext
End Set
End Property
Public Sub New(con As String)
m_ConStr = con
End Sub
Public Sub ExecuteNonQuery()
Using con As New SqlConnection(m_ConStr)
Using com As New SqlCommand(m_Commandtext, con)
com.Parameters.AddRange(m_SqlParameters.ToArray())
con.Open()
com.ExecuteNonQuery()
con.Close()
End Using
End Using
End Sub
End Class
What I've changed:
Changed the class name to SqlCommandManager to be in line with Microsoft's recommendations (don't capitalize more than 2 letters in an abbreviation; IO is fine, Sql and Xml should not be all capitalized)
I would use a List(Of SqlParameter) rather than an array - much easier to deal with, much easier to add additional parameters to it
I prefer to pass the CommandText and the SqlConnection right into the constructor of the SqlCommand - that way,you definitely never forget these two vital bits of information!
Just before your .ExecuteQuery, add the parameters defined in your list to the parameter array of the SqlCommand using a single call to .AddRange()