Search DataTable with values from another table - vb.net

I'm trying to search one DataTable with values from anotherDataTable using LINQ, but no progress so far... How to do it?
In example below i have table, in which i search, and PlTable, which has only one column; and i need to retrieve every row from table, in which the Name field contains at least one string of Name field in PlTable's rows.
Dim ePlTable As IEnumerable(Of DataRow) = PlTable.AsEnumerable()
Dim found = From row In table.AsEnumerable
Where row(0).Contains(ePlTable)
Select row
Return found.CopyToDataTable.Rows
Surely it does not work, as .Contains wants String as argument

Surely it does not work, as .Contains wants String as argument
That's exatly the problem, so use the strongly typed Field extension
method to cast it to it's correct type and Enumerable.Any to look if at least one string is contained in this Name:
Dim strings = From row In PlTable Select row.Field(Of String)(0)
Dim found = From row In table.AsEnumerable
Where strings.Any(Function(s) row.Field(Of String)("Name").Contains(s))
Select row
Return found.CopyToDataTable()

Related

iam trying to get datable specific columns which has null value using linq in vb.net get only those 2 empty rows

When I check the column values in a DataTable using LINQ, they are not equal. Here is the code I'm using which has the problem:
for eg if columnA 5 rows which two or empty ir null i should
DT.
Select("Source <> ('AMEX','VISA')").
ToList().
ForEach(Sub(row) row(ColumnExpType)="T")
To get all the rows, using LINQ, which have NULL in ColumnA you could do something like this:
DT.Rows().
Cast(Of DataRow).Where(Function(row) row("ColumnA") Is DBNull.Value)
However, depending on your needs, you may prefer to use the old Select method:
DT.Select("ColumnA IS NOT NULL")
If you also need to check if the column contains an empty string, then to do that with Select:
DT.Select("ColumnA IS NOT NULL OR ColumnA = ''")
But, if you want to use LINQ, then it depends on the type of the column and whether it's a typed DataTable (a table from a typed DataSet). If the column is a standard string type, like NVARCHAR in T-SQL, and the DataTable is just a standard non-typed DataTable, then you could do something like this:
DT.Rows().
Cast(Of DataRow).
Where(Function(row) row("ColumnA") Is DBNull.Value Or DirectCast(row("ColumnA"), String) = "")
Select("Source <> ('AMEX','VISA')") will not work.
You need
Select("Source <> 'AMEX' And Source <> 'VISA'")
Not sure what the For Each is doing. This is a working example of using my test database.
Dim lst = dt.Select("Rating <> 'Unrated' And Rating <>'Good'").ToList
For Each dr As DataRow In lst
Debug.Print(dr("Name").ToString)
Next

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

Rowfilter Select syntax using a value stored in a variable

I am using VB.NET and I need to use Datatable.Select to get a row which has a matching value.
Consider I have Datatable_A, which has many rows. I am interested to get row/rows which matches my search criteria. In this case, I must get a row (RowA), which has AnswerA stored in Column_A.
I know I can easily use the method below to find the answer:
RowA = Datatable_A.Select("Column_A = 'AnswerA'")
However, value 'AnswerA' is stored in Variable_A.
I have tried using
RowA = Datatable_A.Select("Column_A = 'Variable_A'")
Unfortunately, I still could not get the datarow, whose Column_A = 'Answer A'.
I have studied the explanation in this website DataView RowFilter Syntax [C#], but I could not find any clue there.
Thank you.
If you want to select a subset of your datatable rows using the Select method and a variable that contains the value to filter your rows you need to write
Dim Variable_A = "MySearchCriteria"
Dim rowsSelected = Datatable_A.Select("Column_A = '" & Variable_A & "'")
This means that you want all the rows in which the Column_A (a string column) contains exactly the value "MySearchCriteria" stored in the Variable_A. The filter condition is created concatenating the literal string describing the name of the column and the operator with the content of the Variable_A. Since Column_A is assumed to be a string column then you need to encapsulate the Variable_A between single quotes.
And remember that Select returns an array of DataRow that match the filter expression.
For Each row in rowsSelected
Console.WriteLine(row("Column_A").ToString)
Next

DataTable.Select with converting string value to Date format and sort it

I have a data table that is being returned by a 3rd party component, so I have no way of changing the SQL string to get what I want. So, I get a table with several columns, all of them are Strings. One of the columns is BILLDATE which is of type string, but actually holds a date in a MM/DD/YYYY format.
Issue: I need to sort the records in descending order and pick the record with the biggest date.
CODE:
Dim dataRows As DataRow()
Dim dt As New DataTable
dt = GetTable()
dataRows = dt.Select("", "BILLDATE DESC")
Sample data:
10/23/2010
9/23/2010
8/23/2010
7/23/2010
6/23/2010
From the sample data, the 9/23/2010 record is returned as the first record, not the 10/23/2010.
Here is what I tried:
dataRows = dt.Select("MAX(CONVERT(DateTime,BILLDATE))", "") - run-time Error
dataRows = dt.Select("", "Convert(BILLDATE,'System.DateTime')") - run-time Error
I would prefer not to iterate through all the records to get the latest date and select it. Any ideas?
EDIT 1 - 2012-12-07 4:42pm:
Added definition for dataRows. It is of type DataRow()
You can use DateTime.ParseExact with multiple format strings. You need them since your "dates" sometimes have one and sometimes have two places. I would use Linq instead:
Dim ordered = From row In dt.AsEnumerable()
Let billDate = Date.ParseExact(
row.Field(Of String)("Billdate"),
{"MM/dd/yyyy", "M/dd/yyyy"},
Globalization.CultureInfo.InvariantCulture,
Globalization.DateTimeStyles.None)
Order By billDate Descending
Select row
' if you want to create a new DataTable from the rows: '
Dim tblOrdered = ordered.CopyToDatatable()
Dim LastDate As Date = dt.AsEnumerable().Max(Function(a) Convert.ToDateTime(a("BILLDATE")))

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