Linq where 'not like' or ! <> equivalent in - vb.net

I've got this working :
Dim locations = From row In allLocations.AsEnumerable()
Where row.Field(Of String)("PartNr") Is Nothing
Select row
It gets all the locations where there is no partnumber.
But i would like to do something like this to get everything except some record(s):
Dim locations = From row In allLocations.AsEnumerable()
Where row.Field(Of String)("PartNr") Not Like "12345"
Select row

A simple string contains (ie. equivalent to SQL's like '%substring%') can be done with String.Contains:
Dim locations = From row In allLocations.AsEnumerable()
Where not row.Field(Of String)("PartNr").Contains("12345")
Select row

I've found a solution for what i was looking for:
Dim rgx As New Regex("^G[A-Z]")
Dim alleLocaties = From row In beginQuery.AsEnumerable()
Where (Not rgx.IsMatch(row.Field(Of String)("Location"))
In this example i get all the locations that do not start with G followed by a letter.

Related

Equals() function with multiple values instead of one

I have been using the following since a few years:
Dim mycol = xml.First(Function(x) CStr(x.Attribute("name")).Equals("Source"))
Now I would like to retrieve if either the name attribute is equal to "Source" or "Input".
Does any solution exist for this case?
I have tried the following without any success
Dim cases As String() = {"Source", "Input"}
Dim mycol = xml.First(Function(x) CStr(x.Attribute("name")).Equals(cases))
You would reverse the order of the comparison and use Contains:
Dim mycol = xml.First(Function(x) cases.Contains(CStr(x.Attribute("name"))))

Retrieve the latest or the last value of a column in a dataset

The below code gives the first row.. but i need to get the latest or the last row updated. Please help
Dim dt As DateTime = ds.Tables(0).Rows(0)("Columnname")
You can use the Rows.Count property as shown in other answer or just let do that to Linq
Dim row = ds.Tables(0).AsEnumerable().Last()
Dim dt As DateTime = row.Field(Of DateTime)("ColumnName")
Of course this works for the last row of the table. This doesn't mean something like the last (more recent) value for the "ColumnName". If this is your intention then you need to "Sort" the datatable or better ask the source (a database ? ) of the rows to sort it.
If you are not able to change the data loading query to have it sorted directly from the database engine then you could reach (in code) the latest row ordered by "ColumnName" using something like this
' Create a dataview from the datatable, with no filter and ordered by ColumnName
Dim dv As DataView = New DataView(ds.Tables(0), "", "ColumnName ASC", DataViewRowState.CurrentRows)
dt = dv.Cast(Of DataRowView).Last().Row.Field(Of DateTime)("Column")
You have to use ds.Tables(x).Rows.Count-1
Dim dt As DateTime = ds.Tables(0).Rows(ds.Tables(0).Rows.Count - 1)("Columnname")

Distinct ComboBox Items

I am trying to convert sql to entity and I need to select distinct items. I thought this would work but its returning all the rows instead of the distinct items.
Dim OrderNos = (From r In Orders.R3Delivery Where r.mainOrderNumber <> "" Select r).Distinct().ToList()
For Each thisentry In OrderNos
cbOrderNumbers.DisplayMember = thisentry.mainOrderNumber
cbOrderNumbers.ValueMember = thisentry.mainOrderNumber
Next
Also is their any good free sql to linq tools out their linquer good but its like 60 quid
The problem is that the Distinct() is comparing the entire object being returned, not just the order number.
If you only need the order numbers, changing this line should get you there:
Dim OrderNos = (From r
In Orders.R3Delivery
Where r.mainOrderNumber <> ""
Select r.mainOrderNumber).Distinct().ToList()
If you need the whole object, then it gets more complicated.

Error when using linq on datatable

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()

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