Finding Duplicates based On A Property In Object - vb.net

I want to check for duplicates based on a field in an object.
I have an object called Item that has 3 properties
ID
Rank
Name
I have a list of type Item in a container called
lstTheItems
I am using this code to check for duplicates
'lstTheItems IS NOT CORRECT
Dim duplicates = lstTheItems.GroupBy(Function(i) i) _
.Where(Function(g) g.Count() > 1) _
.[Select](Function(g) g.Key)
How do I return duplicate items base on the Name property?

Dim duplicates = svgGrpContainer.Select(Function(x) svgGrpContainer.Count(Function(y)) > 1));
This means that we will select all the elements which appear more than once in the svgGrpContainer.
Function(x) = one element of svgGrpContainer
svgGrpContainer.Count = go through all the elements getting the count of..
Function(y) > 1 = means that we will take all the element which appear more than once
I hope this helps

Dim duplicates = svgGrpContainer.GroupBy(Function(x) x.Name).Where(Function(x) x.Count > 1).Select(Function(x) x)

You need to group it by the Name, no the object itself. Also, you probably want to get the entire object back in your duplicate list, not just the key (in this case the name).
Dim duplicates = lstTheItems.GroupBy(Function(i) i.Name) _
.Where(Function(x) x.Count() > 1) _
.[Select](Function(x) x)

Related

Getting duplicates using Linq on strongly typed table

I'm looking for duplicates in a table based on Name, Date and Category all being the same. I want both (or all) of the duplicated rows in my result set. I'm using VS 2008 with .net 3.5. I'm starting with data in a strongly typed table and want to end up with only duplicates on the same table or in a copy of the table. I'm using the data table as the source for a report.
I've spent a lot of time checking out similar questions but have not found an answer.
Dim LList as PmtDataTable = PmtList.GroupBy(x => New {x.Name, x.PmtDate, x.Category}) _
.Where(x => x.Count() > 1) _
.select(x => New {x.key, Values = x.tolist()})
I got the syntax from https://stackoverflow.com/a/15747265/2559297 but since I'm using old VS it's not working for me. Can you translate this to VS 2008 with .net 3.5?
You missed the keyword Key
And you missed the C# and VB.NET :) (I am a C# developer).
Try this:
Dim query = PmtList.GroupBy(Function(x) New With {Key .Name = x.Name, Key .PmtDate = x.PmtDate, Key .Category = x.Category}) _
.Where(Function(x) x.Count() > 1) _
.Select(Function(x) New With {.KeyName = x.key, .Count= x.Count()})
#Tim.Tang's answer is close. But I need it to feed back to a PmtDataTable. So changed his Select statement to return the groups. Then I get the rows and add the data to a new data table.
Dim dupList = PmtList.GroupBy(Function(x) New With {Key .Name = x.Name, _
Key .PmtDate = x.PmtDate, _
Key .Category = x.Category}) _
.Where(Function(y) y.Count() > 1) _
.SelectMany(Function(grp) grp)
Dim PmtList2 As New PmtDataTable
For Each rw as PmtRow In dupList
Dim iRow As PmtRow
iRow = PmtList2.NewPmtRow
iRow.ItemArray = rw.ItemArray
PmtList2.AddPmtRow(iRow)
Next

Linq query to display unique set of names for current data set

I have a linq query that is used to display the list of requests from multiple users.And a Requestor can have multple requests(So the grid can have same Requestor multiple times). Now i am creating a dropdown list with unique Requestor that are displayed on the grid.(issue is i am not getting the distinct list but getting all the Requestor multiple times). Below is the linq query i am unsing.Can anyone suggest with correct linq query.
Dim rqstQry = From x In db.Request_vws _
Order By x.RequestID Descending _
Select x.RequestID,
Descr = x.Descr, _
RequestorName = String.Format("{0} {1}", x.FIRST_NAME, x.LAST_NAME), _
RelatedTask = GetTaskDescr(x.WorkID, x.TaskLabel, x.TaskDescr), _
RequestDescr = GetRequestDescr(x.RequestType), x.SubmitDttm, x.UpdatedDttm, _
x.ChangeDttm, _
x.MigrTimeStr, x.MigrApptTime, _
x.Requestor Ditinct
DataBind:
RequestorCB1.DataSource = rqstQry
RequestorCB1.DataTextField = "Requestor" RequestorCB1.DataValueField = "REquestor"
RequestorCB1.DataBind()
Need distinct user in the dropdownlist
Put parentheses around the LINQ query and append .Distinct()
Dim rqstQry = (From x In db.Request_vws _
Order By x.user
Select x.user).Distinct()
If you are including Request stuff in the result, then you cannot get distinct users (as Gert Arnold points out in his comment). Only include columns related to users.
If you still need information on requests then you must limit this information to one record per user. You would use a group by and use an aggregate in order to select a request (the first one, the last one etc.).
Got this by using the below query.
Dim rqstQry = (From x In db.Request_vws _
Order By x.RequestID Descending _
Select x.RequestID,
Descr = x.Descr, _
RequestorName = String.Format("{0} {1}", x.FIRST_NAME, x.LAST_NAME), _
RelatedTask = GetTaskDescr(x.WorkID, x.TaskLabel, x.TaskDescr), _
RequestDescr = GetRequestDescr(x.RequestType), x.SubmitDttm, x.UpdatedDttm, _
x.ChangeDttm, _
x.MigrTimeStr, x.MigrApptTime, _
x.Requestor). Distinct()
Dim rqstQry2 = (From y In rqstQry _
Select y.Requestor, y.RequestorName).Distinct()

select multiple rows from datagridview and show the IDs

I'm doing a simple quiz program.
Here's how my program works: User can choose from two options;
either choose only one category(DropDownList)
choosing multiple category(where multiple rows are selected from the DataGridView)
For now I just want that if user choose multiple rows, all the IDs of the rows selected must be shown in MsgBox(). Is there anyway that I can do it? Thank you in advance.
Edited
Okay, so far I have this:
Dim id, i, j As Integer
Dim idList(1)
For Each selectedItem As DataGridViewRow In qstSets.SelectedRows
'show ids of multiple selected rows
id = qstSets.SelectedRows(0).Cells("ID").Value
idList(i) = id
i += 1
Next selectedItem
For j = 0 To 1
MsgBox("Element " & j & " = " & idList(j))
Next j
I have planned to safe the id's of selected row in array and then display it. But the problem here is that, I keep getting only one id in the Element when I have selected 2
(Posted on behalf of the OP):
Thank you for your help #cyril
Dim id, i As Integer
Dim idList(5)
For Each selectedItem As DataGridViewRow In qstSets.SelectedRows
'show ids of multiple selected rows
id = selectedItem.Cells("ID").Value
idList(i) = id
i += 1
Next selectedItem
Dim sResult As String = ""
For Each elem As String In idList
sResult &= elem & ", "
Next
MsgBox(sResult)
You can iterate over all selected datagridview rows:
For Each selectedItem As DataGridViewRow In DataGridView1.SelectedRows
For getting the Id or any value you like, please have a look to:
DataGridView get column values
To show ID's and select Multiple rows in datagridview I think it would be helpful to You.
Dim SelectedRow as datagridview.selectedrow(0)
Dim selectedID as selectedRow.cells("ID").value
Dim Row as Datarow
Dim IDLists as List(of integer)
For i = 1 To datagridview.SelectedRows.Count()
selectedRow = datagridview.SelectedRows(i - 1)
selectedID = selectedRow.Cells(0).Value
row = _table.Select("ID =" & selectedID).FirstOrDefault()
IDlists.add(selectedID)
Next
for j = 0 to IDLists.count
messagebox.show(IDlists(j))
Next
I think This will be helpful If I am wrong correct me

linq using order by, where, and select vb.net

I have a Linq query that I am passing to a list, and then to the view through the viewbag. I am trying to keep that list in a specific order, so that when I iterate through it I have control over the order in which it's displayed.
Here is the query:
ViewBag.attributes = (From row In db.tblCategory_Attributes
Where row.Item_Type_Identifier = itemType
Order By row.Category_Attribute_Identifier
Select CStr(row.Attribute_Name)
Distinct).ToList()
I am successfully passing this list to the view and iterating through it, but no matter what the values are always displayed in alphabetical order. Category_Attribute_Identifier is an integer that aligns with the order I would like these values to be displayed in.
I've played around with the order of my statements quite a bit and I'm not having any luck.
Can you tell me how to distinctly select the Attribute_Name's that correlate with my specific Item_Type_Identifier and order my results by the Category_Attribute_Identifier?
The Distinct is creating its own ordering again (because it shuffles through the result to filter out duplicates). Just do the sorting after the Distinct:
(From row In db.tblCategory_Attributes
Where row.Item_Type_Identifier = itemType
Select row
Distinct)
.OrderBy(Function(row) row.Category_Attribute_Identifier)
.Select(Function(row) CStr(row.Attribute_Name))
Try using Group By instead of Distinct
ViewBag.attributes = (From row In db.tblCategory_Attributes _
Where row.Item_Type_Identifier = itemType _
Order By row.Category_Attribute_Identifier) _
.AsEnumerable() _
.GroupBy(Function(r) r.Attribute_Name) _
.Select(Function(g) g.Key) _
.ToList()
Or use the extension method syntax which gives you the freedom of applying the extension methods in any order:
ViewBag.attributes = db.tblCategory_Attributes _
.Where(Function(row) row.Item_Type_Identifier = itemType) _
.Select(Function(row) New With {row.Attribute_Name, row.Category_Attribute_Identifier}) _
.Distinct() _
.OrderBy(Function(a) a.Category_Attribute_Identifier) _
.Select(Function(a) a.Attribute_Name) _
.ToList()
This simple test demonstrates that GroupBy preserves the order:
Public Shared Sub TestGroupOrder()
Dim a = New Integer() {6, 2, 4, 2, 7, 5, 3, 4}
Dim query = a.GroupBy(Function(i) i).[Select](Function(g) g.Key)
For Each i As Integer In query
Console.Write("{0} ", i)
Next
End Sub
Result in the console:
6 2 4 7 5 3

Enumeration yielded no results

I am trying to insert/update my table using the values in the grid
Given below is the code I'm using to get the productId in the grid:
Dim prodId = From row As DataRow _
In grdSale.Rows _
Where row.Item(0).ToString <> "" _
Select row.Item(0)
I am getting productid correctly. Given below is the code to get the value in QTY column with respect to the productId:
For Each id As Long In prodId
Dim intpdt As Long
intpdt = id
intQty = (From row As DataRow In grdSale.Rows Where _
row.Item(0).Equals(intpdt) _
Select row.Item("QTY")).FirstOrDefault()
Next
In intQty I am getting 0 but it should be 10 or 12 as you can see in the QTY column in the grid (Enumeration yielded no results).
Where am wrong?
Try doing this and see if you get the result you expected:
intQty = _
( _
From row As DataRow In grdSale.Rows Where _
CLng(row.Item(0)) = intpdt _
Select CInt(row.Item("QTY")) _
).FirstOrDefault()
Not sure what causes your issue, but you should use the Field extension method since it is strongly typed and supports nullable types. I also don't understand why you need the additional loop and query to find the quantity of each product. This should do both:
Dim prodQTYs = From row In grdSale.Rows.Cast(Of DataRow)()
Let ProductID = row.Field(Of String)("ProductId")
Let Quantity = row.Field(Of Long)("QTY")
Where Not String.IsNullOrWhiteSpace(ProductID)
Select New With {.ProductID = ProductID, .Quantity = Quantity}
Change the types to the appropriate ones.
Output:
For Each prodInfo In prodQTYs
Console.WriteLine("Product:{0} Quantity:{1}", prodInfo.ProductID, prodInfo.Quantity)
Next