How to select replicated items in a list with linq? - vb.net

Hy Guys!
I have a list of "ObjDay" which could have replicated items. How can I select them?
ObjDay is:
Public class ObjDay
_date
...
End Class
I tried to do:
replicatedItems = From d In ObjDaysList _
Order By d._date _
Group d By d._date Into newGroupOfObjDays = Group _
Where newGroupOfObjDays.Count > 1 _
Select newGroupOfObjDays
But I'm getting this error:
Can't convert object of type 'WhereSelectEnumerableIterator2[VB$AnonymousType_02[System.DateTime,System.Collections.Generic.IEnumerable1[ObjDay]], System.Collections.Generic.IEnumerable1[ObjDay]]'
in type 'System.Collections.Generic.List`1[ObjDay]'.
Tks for help!

You're selecting groups, and trying to assign it to a List(Of ObjDay). That won't work. You could do:
'Get groups of duplicate items
Dim groups = From d In ObjDaysList _
Order By d._date _
Group d By d._date Into newGroupOfObjDays = Group _
Where newGroupOfObjDays.Count > 1 _
Select newGroupOfObjDays
'Get all items from these groups with SelectMany
replicatedItems = groups.SelectMany(Function(item) item).ToList

Related

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

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

Sorting Linq results ascending using subselect and then descending

I am trying to work out a LINQ query to pull items from a List, the List contains a child-nested List - which I need to query for an item, then use the resulting item in my final sort of all records returned the query.
The parent is List(Of MediaItems) - the class structure as follows:
MediaItems
.ID (int)
.Src (string)
.Advert (bool)
.AdOptions As List(Of AdvertOptions)
.Counter (int)
AdvertOptions class consists of:
.Age (int)
.Gender (int)
.Priority (int)
I want to query for any MediaItems that meet the following criteria:
.Advert = true
.Age = x (paramter in calling function)
.Gender = y (paramter in calling function)
To do this, I am using the following LINQ query: (Age and Gender are the function parameters)
Where(Function(s) s.Advert And s.AdOptions.Any(Function(a) a.Gender = Gender And a.Age = Age))
I now need to sort the results based on two sorting levels:
AdOptions.Priority (in descending order), then sort by Counter in ascending order
This is my failing attempt:
Where(Function(s) s.Advert And s.AdOptions.Any(Function(a) a.Gender = Gender And a.Age = Age)).OrderBy(Function(a) From p1 In a.AdOptions Where p1.Gender = Gender And p1.Age = Age Select p1.Priority).ThenByDescending(Function(s) s.Counter)
My attempt is not working, I am getting the following error:
at least on object must implement IComparable
Can anyone see what needs to be done to achieve my goal?
Ben
On reading your code a bit closer, I spotted that you order by AdOptions
I think this is what you really want
Sub Demo(ByVal gender As Integer, ByVal age As Integer)
Dim items = New List(Of MediaItem)()
Dim matching = Function(a) a.Gender = gender And a.Age = age
Dim ads = items.Where(Function(s) s.Advert And s.AdOptions.Any(matching))
Dim sorted = ads _
.OrderBy(Function(a) a.AdOptions.Where(matching).Max(Function(ao) ao.Priority)) _
.ThenByDescending(Function(s) s.Counter)
' if you really wanted a sorted list of AdOptions, you'd write
Dim optionlist = ads.OrderByDescending(Function(s) s.Counter) _
.SelectMany(Function(a) a.AdOptions.Where(matching).OrderBy(Function(ao) ao.Priority))
' to combine the two previous options
Dim adsWithOptions = ads.OrderByDescending(Function(s) s.Counter) _
.Select(Function(a) New With { _
.Ad = a, _
.Options = a.AdOptions.Where(matching) _
.OrderBy(Function(ao) ao.Priority) _
})
End Sub

Group by and order by

using LINQ to NHibernate does anybody know how to use group by and order by in the same expression. I am having to execute the group by into a list and then order this, seem that I am missing soemthing here ???
Example:-
Private function LoadStats(...) ...
Dim StatRepos As DataAccess.StatsExtraction_vwRepository = New DataAccess.StatsExtraction_vwRepository
return (From x In StatRepos.GetAnswers(Question, Questionnaire) _
Group x By xData = x.Data Into Count() _
Select New ChartData
With {.TheData = xData,
.TheValue = xData.Count}
).ToList.OrderBy(Function(x) x.TheData)
End Sub
I'm not a Visual Basic expert, but you should be able to use alias in the Select clause to create a temporary variable, so that you can refer to it in a later clauses such as Order By. Unless there is some limitation in NHibernate, the following should work:
return From x In StatRepos.GetAnswers(Question, Questionnaire) _
Group x By xData = x.Data Into Count() _
Select res = New ChartData With _
{ .TheData = xData, _
.TheValue = xData.Count } _
Order By res.TheData _
Select res
I guess that in some situations, this may be more readable than moving the Order By clause before the Select clause.