Public Function GetCategories() As DataSet
Dim query As String = "SELECT * FROM Categories"
Dim cmd As New OleDbCommand(query)
Return FillDataSet(cmd, "Categories")
End Function
Presumably, you haven't actually defined the FillDataSet method.
I think you may have meant to use the SqlDataAdapter's Fill method. You can see a complete example of how to do that here: Direct method from SQL command text to DataSet
Related
I have two Layes Classes Business Layer And Data Layer And i have The Main class i called DatabaseManager contain all functions i need for stored procedures
I search on these errors I cannot find solutions
First Error in DatabaseManager class is :
implicit conversion from object to integer
Public Function ExecuteScalar(ByVal sql As String) As Object
Dim cmd As New SqlCommand(sql) With {
.CommandType = CommandType.Text,
.Connection = Connection
}
Dim retval As Integer = ExecuteScalar(cmd)
Return retval
End Function
In Data Layer Class i have this code :
Friend Function Get_Last_Visits_Type(ByRef cmd As SqlCommand)
Dim retval As Integer
cmd = New SqlCommand("Get_Last_Visits_Type")
retval = dm.ExecuteScalar(cmd)
Return retval
End Function
I got two errors here
function without an 'as' clause return type of object assumed
And
implicit conversion from object to integer
When Form Loaded i put this code on Load action :
TxtVisitTypeID.Text = Val(p.Get_Last_Visits_Type)
And i got this error :
implicit conversion from Double to String
Thanks...
Quite a few problems here as mentioned in comments:
Avoid naming a function anything that is a reserved word in the scope of your project at the very least: ExecuteScalar is a method of SqlCommand so use something like MyExecuteScalar instead.
Dim retval As Integer = ExecuteScalar(cmd) probably should be Dim retval As Integer = cmd.ExecuteScalar() unless you want a recursion (which I doubt). (Refer 1.)
Turn Option Strict on in your project settings. As mentioned, ALWAYS have this on. (And I prefer to have Option Explicit on and Option Infer off as well for similar reasons.)
With compile options set as in 3. you will have (valid) compilation errors pertaining to type conversion (at least), with a good chance of resulting in working code once you fix them. Eg Dim retval As Integer = Ctype(cmd.ExecuteScalar(), Integer) (if you're sure that the result of the query will be Integer, otherwise you will need to test and/or error trap).
Connection isn't defined anywhere: .Connection = Connection. You don't pass it nor declare it.
Since retval is declared as an Integer then the return type can also be tightened up to Integer as well, rather than Object.
Your second function has no return type.
What is dm? Not declared/defined.
Consider using Using blocks to close-and-dispose of SQL connection and command on exit.
CommandType.Text is the default so you only need to state it by way of explanation.
Here's what I'd do with your first function:
Public Function MyExecuteScalar(ByVal sql As String) As Integer
Try
Using con As New SqlConnection(sql)
Using cmd As New SqlCommand(sql, con)
Return CType(cmd.ExecuteScalar(), Integer)
End Using
End Using
Catch
Return -1 ' Or something recognizable as invalid, or simply Throw
End Try
End Function
Addressing the first function:
This code is too abstract to be useful. The name of the function is bad. It appears to be recursive but the value you pass back to the function is not a string but a command. If the line of code is Dim retval As Integer = cmd.ExecuteScalar(), then .ExecuteScalar() returns an Object. You cannot convert an Object to an Integer without a conversion method. If you are declaring retval as an Integer why would you have typed your function As Object? I won't even get into the connection problem here. I suggest you delete the function and start again.
Addressing the second function:
Why are you passing the command ByRef? This function has no connection at all! How do you expect it to execute anything? Same problem with retval As Integer and ExecuteScalar returning an Object.
Again, delete and start again.
Now to the code in Form.Load:
Val went out with VB6. I can give unanticipated results. Guess what, Val returns a Double. A .Text property expects a string. Also you appear to be calling the function you showed us above. That function asks for the calling code to provide an argument, namely an SqlCommand object.
My suggestions:
Forget about layers and try to learn the basics of data access with ADO.net. Turn on Option Strict now and forever. Ask new questions with a single problem. Tell us what line the error occurs on. You have been advised before that functions require a datatype but it doesn't seem to sink in.
I have the following code in my code behind:
Dim name As String
name.text= Staff.LoadName(StaffID)
The following query in my Class:
Public Function LoadName(ByVal ID As String)
Dim ds As New DataSet
Dim SQL As String = ""
SQL="select name from Staff where StaffID='" & ID & "' "
ds = Common.QueryDataByDataset(SQL)
ds.Tostring()
Return ds
End Function
But the name.Text doesn't show the value. How to I get the single value and convert it to string to display? Thanks
I am guessing the Common.QueryDataByDataset is from your library or some third party. Assuming it is executing the query and populating the dataset, you should be able to change the last two lines of the LoadName function to this:
String name = ds.Tables.Item("Staff").Rows(0)("name").ToString()
return name
You should add error handling in this method. For example, check to make sure the query returns exactly one result. Also, this method appears to be susceptible to SQL injection: http://en.wikipedia.org/wiki/SQL_injection
Here is an example of my function:
Public Class GlobalFunctions
Public Shared Function CreateNewDatabase(ByVal MyDomainName As String, ByVal NewDatabaseName As String, ByVal StatusBoxName As ListBox)
Try
Dim MyWorkingDirectory As String = "C:\mytest1\"
Dim MyFileName As String = "mycmd.exe"
If File.Exists(MyWorkingDirectory & MyFileName) Then
'Run mycmd
'Here are my results
Dim Result1 As String = "r2"
Dim Result2 As String = "r2"
Dim Result3 As String = "r3"
End If
Catch ex As Exception
MsgBox(ex.Message)
End Try
Return True
End Function
End Class
Basically what I need to do is run my function & then be able to use the results in my next function.. Something like:
GlobalFunctions.CreateNewDatabase(DomainName.Text, MyDbName, StatusListBox)
MsgBox(Result1)
MsgBox(Result2)
MsgBox(Result3)
Any help would be much appreciated ;)
There are two main options here. The first is to return the values you want to use later. To do this, you can either create a class with properties for the three values you want to use, or if this function will have limited use, you could consider returning a Tuple (based on your example, a Tuple(Of String, String, String))
The other option is to make class level properties and set their backing fields from the CreateNewDatabase function. The primary drawback to this is that these values will be overwritten by any future calls to the function. It also introduces some discoverability issues into your API by requiring the programmer to know that three properties are set by the method, rather than the more obvious returning an object with three properties from the function.
You should make properties Result1, Result2, Result3 in your class and set them in CreateNewDatabase(). Then you can get them as GlobalFunctions.Result1
But it looks terrible.
Well, the obviously easiest way is, declaring them as global variables, which in practice seems not to be too welcomed.
Public Class Form1
Dim Result1 As String
Dim Result2 As String
Dim Result3 As String
GlobalFunctions.CreateNewDatabase(DomainName.Text, MyDbName, StatusListBox)
MsgBox(Result1)
MsgBox(Result2)
MsgBox(Result3)
etc..
etc...
end class
Not the prettiest way to do it, but it will get the job done.
Ok, just needing a 2nd set of eyes looking at this to make sure the error isn't something else other than my LINQ code here. Here's the function class itself:
Public Function GetJacketByPolicyID(ByVal jacketID As Int32) As tblPolicy
Dim db As New DEVDataContext()
Dim j As tblPolicy = db.tblPolicies.Single(Function(p) p.policyNumber = jacketID)
Return j
End Function
and here is the code which calls this class function in the web control form itself:
Dim p As tblPolicy
Dim j As New Jackets()
p = j.GetJacketByPolicyID(3000050)
For some reason it's flagging the 2nd line in the GetJacketByPolicyID function saying the specified cast is not valid. So I'm guessing it's something I'm doing wrong. I'm sure the tblPolicy/tblPolicies class works right since I can create a new instance of a tblPolicy and set a few variables by hand and return it, so that's not it. I've also checked the datarow I'm fetching and there's no null values in the record, so that shouldn't be it either.Any help much appreciated.
This would seem to get what you are looking for. Not sure why you are passing in a function for a simple query like this.
Public Function GetJacketByPolicyID(ByVal jacketID As Int32) As tblPolicy
Dim _jacket as tblPolicy
Using _db As New DEVDataContext()
_jacket = (From _j In db.tblPolicies Where _j.policyNumber.Equals(jacketID) Select _j).Single()
End Using
Return _jacket
End Function
I am pretty new to VB.NET and am having a bit of trouble here with something I thought should be simple.
Keeping it simple, let's say I have a Document table with "Name" that I want to search on (in reality there are several other tables, joins, etc. ..). I need to be able to build the query using a where clause based on string values passed in.
Example - the user may pass in "ABC", "ABC DEF", "ABC DEF GHI".
The final query would be (the syntax is not correct, I know):
Select * from Documents Where Name Like %ABC% AND Name Like %DEF% AND Name like %GHI%
So, I thought I could do something like this.
Dim query = From document In _context.Documents
<< loop based on number of strings passed in >>
query = query.Where( ... what goes here?? )
For some reason, being brain-dead or something, I can't figure out how to make this work in VB.NET, or if I'm doing it correctly.
I believe this is how you would do it in VB (I'm a C# developer):
query = query.Where(Function(s) s = "ABC")
See LINQ - Sample Queries for some examples.
I think the tricky part here is the unknown number of query parameters. You can use the underlying LINQ IQueryable(Of T) here to help.
I think the following would work (it's not compiled, just notepad code here):
Public Function GetDocuments(criteria as String)
Dim splitCriteria = SplitTheCriteria(criteria)
dim query = from document in _context.Documents
For Each item in splitCriteria
Dim localItem = item
query = AddCriteriaToQuery(query, localItem)
Next
dim matchingDocuments = query.ToList()
End Function
Private Function AddCriteriaToQuery(query as IQueryable(Of Document), criteria as string) as IQueryable(Of Document)
return query.Where(Function(doc) doc.Name = criteria)
End Function
Since LINQ will delay-execute the query you can append where clauses onto your query in the loop and then call .ToList() at the end to execute the query.
In LINQ to SQL you can add WHERE clauses to your query using the .Where method of the query object, as you noted in your question. To use the LIKE operator, try using the .Contains method of the object you're querying in the Lambda expression of your call to the Where method.
Here's a simplified example in a console application. Hopefully it will lead you in the correct direction.
Public Class Doc
Private _docName As String
Public Property DocName() As String
Get
Return _docName
End Get
Set(ByVal value As String)
_docName = value
End Set
End Property
Public Sub New(ByVal newDocName As String)
_docName = newDocName
End Sub
End Class
Sub Main()
Dim Documents As New List(Of Doc)
Documents.Add(New Doc("ABC"))
Documents.Add(New Doc("DEF"))
Documents.Add(New Doc("GHI"))
Documents.Add(New Doc("ABC DEF"))
Documents.Add(New Doc("DEF GHI"))
Documents.Add(New Doc("GHI LMN"))
Dim qry = From docs In Documents
qry = qry.Where(Function(d) d.DocName.Contains("GHI"))
Dim qryResults As List(Of Doc) = qry.ToList()
For Each d As Doc In qryResults
Console.WriteLine(d.DocName)
Next
End Sub
Note the .Contains("GHI") call in the Lambda expression of the .Where method. I'm referencing the parameter of the expression, "d", which exposes the DocName property, which further exposes the .Contains method. This should produce the LIKE query you're expecting.
This method is additive, i.e. the call to the .Where method could be enclosed in a loop to make additional LIKE operators added to the WHERE clause of your query.
Dim query = From document In _context.Documents where document.name = 'xpto' select document
Or
Dim query = From document In _context.Documents where document.name.contains('xpto') select document
If you do this in a loop, you can do something like this:
.Where(Function(i as mytype) i.myfiltervar = WhatIWantToSelect)