Error when using linq on datatable - vb.net

I am trying to run the following code converting my datatable to be usable in linq all seems fines and compiles but when I Execute the statement I get the following statement i get the error below new entires just has location and ordernumber in the return values I have to do it this way as I am supporting a legacy access 97 system thanks.
Dim total = From row In newEntries.AsEnumerable()
Select row.Field(Of Int32)("location") Distinct
retVal = Convert.ToInt32(total)
This is my whole code but im still getting an invalid type cast error their is data exsits for this order by teh way
Dim retVal As Int32
Dim newEntries As New DataTable
Dim script As String = scriptBuilder.GetDistinctOrdersForLocations(OrderNumber)
newEntries = connection.SqlSelectToDataTable(script)
Dim total = From row In newEntries.AsEnumerable()
Select row.Field(Of Int32)("location") Distinct
retVal = total.Count()

If you want the count of the collection just do this:
retVal = total.Count()
this will return the count from the distinct query that you have written.
Just to clarify, #David B identified the data type of location was int16 not int32, so changing this in the linq query resolved the issue.

Your LINQ query is returning a collection. You should use something like First or FirstOrDefault.
I'm a little rusty on VB LINQ, but try :
retVal = Convert.ToInt32(total.First())
Note: This will throw an error if there are no items in the collection.

It's important to understand when you write a LINQ query and assign it to a variable, that variable essentially contains a query object, and not the results of running the query. In order to get the value that results from the query, you need to call some method on the query object such as:
total.Single() ' Assumes you expect the query to return exactly one result.

I changed the code to int16 worked here is the code for any one else stuck thanks #Ric
Dim retVal As Int32
Dim newEntries As New DataTable
Dim script As String = scriptBuilder.GetDistinctOrdersForLocations(OrderNumber)
newEntries = connection.SqlSelectToDataTable(script)
Dim total = From row In newEntries.AsEnumerable()
Select row.Field(Of Int16)("location") Distinct
retVal = total.Count()

Related

SQL variable returning 0

When I run the following SQL statement in SQL Server Management Studio it returns a count of 2
SELECT COUNT(*)
FROM Daisy_Copy2
WHERE ChargeCode = '1';
But for some reason when I run the following VB.net code the result variable returns a 0 and doesn't identify that duplicate codes exist.
Dim result As Integer
Using cmdb = New SqlCommand("SELECT COUNT(*) FROM Daisy_Copy2 WHERE ChargeCode = '1'", conn)
Int(result = cmdb.ExecuteScalar())
If result > 1 Then
MessageBox.Show("Duplicate Codes Exist!", "Billing", _
MessageBoxButtons.OK, MessageBoxIcon.Information)
Else
MsgBox(result)
End If
End Using
Can anyone help me understand why?
Any help greatly appreciated.
Instead of ExecuteNonQuery you should use ExecuteScalar
Dim result As Integer = CInt(cmd.ExecuteScalar())
ExecuteNonQuery is normally used for updates or inserts that don't leave a result, so it returns an integer telling you how many rows were affected, not the result itself.
What you most likely are meaning to use is ExecuteScalar which returns the first column of the first row in the result set returned by the query, in this case the integer containing your count.
this is just a way you can use:
Dim Sqlda = New SqlDataAdapter("SELECT COUNT(*) AS tCount FROM Daisy_Copy2 WHERE ChargeCode=1", conn)
Dim sqlds = New DataSet
Sqlda.Fill(sqlds, "Daisy_Copy2")
Dim tblRow As DataRow
For Each tblRow In sqlds.Tables("Daisy_Copy2").Rows
MsgBox(tblRow("tCount").ToString())
Next
use below link to read more about it
System.Data.SqlClient Namespace
Good luck

select count on list using linq on specific value vb.net

I am having an issue getting the results I am looking for. What I need to do is essentially:
Select count(invoicenbr) from invoicelist where invoicenbr = 'invoice'
but when I try it in linq I am not getting the correct results.
When I try to execute the linq query below, it gives me the count for the entire list, and not for the where invoicenbr = 'invoice'...
Here is my linq query that is returning the count for the entire invoiceList:
Dim test = (From invoices In invoicelist _
Where e.Row.Cells("invoicenbr").Value = invoice).count()
You have a naming issue in your code, i assume that it's responsible for your problem.
The variable in your query is invoices but later you use invoice to compare it with the cell value, so you have a different variable in scope with name invoice.
This should work:
Dim invoicenbr As String = e.Row.Cells("invoicenbr").Value
Dim duplicates = From invoice In invoicelist
Where invoice = invoicenbr
Dim duplicateCount As Int32 = duplicates.Count()

DataTable.Select.Where VB.Net - Delete rows

I'm currently pulling information using a query that I'm not allowed to tamper with:
Dim dt As DataTable = BLL.GetData(variable).Tables(0)
Immediately afterwards, I'm removing any records where a field begins with a specific value:
For Each dr As DataRow In dt.Rows
If dr.Item(2).ToString().StartsWith("value") Then
dr.Delete()
End If
Next
What I'd really like to do is something like:
dt.Select.Where(field1 => field1.StartsWith("value")).Delete()
I know that is not the syntax of it and I'm probably very off from what it would be like. The For Each works fine, I'm just trying to "simplify" it. Any idea? Any and all help is appreciated.
Actually, your initial code is probably the cleanest and most straight forward.
To delete items using LINQ, you first need to read them into a separate collection, then loop through that collection and call Delete on each record. If you'd rather go that route, you could try:
Dim records = dt.Rows.Where(Function(r) r.StartsWith("value")).ToList()
For Each r In records
r.Delete()
Next
The answer I think you are looking for is below from Microsoft. https://msdn.microsoft.com/en-us/library/det4aw50(v=vs.110).aspx?cs-save-lang=1&cs-lang=vb#code-snippet-2
Dim table As DataTable = DataSet1.Tables("Orders")
' Presuming the DataTable has a column named Date.
Dim expression As String
expression = "Date > #1/1/00#"
Dim foundRows() As DataRow
' Use the Select method to find all rows matching the filter.
foundRows = table.Select(expression)
Dim i As Integer
' Print column 0 of each returned row.
For i = 0 to foundRows.GetUpperBound(0)
Console.WriteLine(foundRows(i)(0))
Next i

VB.Net - Efficient way of de-duplicating data

I am dealing with a legacy application which is written in VB.Net 2.0 against a SQL 2000 database.
There is a single table which has ~125,000 rows and 2 pairs of fields with similar data.
i.e. FieldA1, FieldB1, FieldA2, FieldB2
I need to process a combined, distinct list of FieldA, FieldB.
Using SQL I have confirmed that there are ~140,000 distinct rows.
Due to a very restrictive framework in the application I can only retrieve the data as either 2 XML objects, 2 DataTable objects or 2 DataTableReader objects. I am unable to execute custom SQL using the framework.
Due to a very restrictive DB access policy I am unable to add a View or Stored Proc to retrieve as a single list.
What is the most efficient way to combine the 2 XML / DataTable / DataTableReader objects into a single, distinct, IEnumerable object for later processing?
I may have missed something here but could you not combine both DataTables using Merge?
DataTableA.Merge(DataTableB)
You can then use DataTableA.AsEnumerable()
Then see this answer on how to remove duplicates or
You can do this with a DataView as follows: dt.DefaultView.ToTable(True,[Column names])
This is the solution I came up with.
Combine the 2 DataTables using .Merge (thanks to Matt's answer)
Using this as a base I came up with the following code to get distinct rows from the DataTable based on 2 columns:
Private Shared Function GetDistinctRows(sourceTable As DataTable, ParamArray columnNames As String()) As DataTable
Dim dt As New DataTable
Dim sort = String.Empty
For Each columnName As String In columnNames
dt.Columns.Add(columnName, sourceTable.Columns(columnName).DataType)
If sort.Length > 0 Then
sort = sort & ","
End If
sort = sort & columnName
Next
Dim lastValue As DataRow = Nothing
For Each dr As DataRow In sourceTable.Select("", sort)
Dim add As Boolean = False
If IsNothing(lastValue) Then
add = True
Else
For Each columnName As String In columnNames
If Not (lastValue(columnName).Equals(dr(columnName))) Then
add = True
Exit For
End If
Next
End If
If add Then
lastValue = dr
dt.ImportRow(dr)
End If
Next
Return dt
End Function

DataTable Select(String) Function Help VB .NET

I made a datatable with 2 columns a transactionTime column and a numberOfTransactions column. I made the table with the pre-defined transaction times and want to add the number of transactions from an XML file. I have gotten through the XML file and want to add the data to the correct row. Here is the function:
Function AddRow(ByVal timeOfTransaction As String, ByVal numberOfTransactions As String, ByRef dataTableOfTransactions As DataTable) As String
Dim row() As DataRow = dataTableOfTransactions.Select("transactionTime = timeOfTransaction")
If row(0) IsNot Nothing Then
row(0)("numberOfTransactions") = numberOfTransactions
End If
Return Nothing
End Function
When I run this it overwrites the first element in the table's numberOfTransactions coloumn. I know it has to do with the "transactionTime = timeOfTransaction" part but I can't seem to get it to read timeOfTransaction as a reference to a string instead of a literal. Any help would be much appreciated. Thanks!
You need to write something like this :
Dim row() As DataRow = dataTableOfTransactions.Select("transactionTime=#" & timeOfTransaction & "#")
But be careful with your date/month or month/date format, it depends of your regional settings.
row(0)("numberOfTransactions") = numberOfTransactions
Right there you are telling the program to overwrite that value with number of transactions.
If you want that value you need to set it to something, not set something to it.
Also, if you want your select to work properly try doing it like this
dataTableOfTransactions.Select("transactionTime = " + timeOfTransaction)