C
C#6mo ago
Mr. Roach

Questions regarding a linq query

Hello there, I'm playing a little bit with linq queries but don't know if i truly understand this. Why do I need to orderby twice here(and group again) in order to get the full result and the parts its made of ordered how I want? I read something about primary and secondary sort and wondered if thats whats happening here. I'm also wondering if this query could be written better/smaller?


from sales in File.ReadAllLines(file).Skip(1)
select sales.Split(",") into sales
select (itemName: sales[1], stackSize: sales[2], quantity: decimal.Parse(sales[3]), price: decimal.Parse(sales[4]), otherPlayer: sales[5]) into grouped
// grouping the selection by otherPlayer and itemNames
group grouped by new { grouped.otherPlayer, grouped.itemName } into grouped
// therefore selecting for each player a grouped view where the values
// for quantity and price of each item that appears gets summed
select new
{
grouped.Key.otherPlayer,
item = grouped.Key.itemName,
quant = grouped.Sum(x => x.quantity),
price = grouped.Sum(x => x.price) / 10000
}
into grouped
// here the results for each otherPlayer but not the whole query are getting ordered(secondary sort?)
orderby grouped.price descending
// if i dont group here again, I cant order by the summed values that each player has, why?
group grouped by new { grouped.otherPlayer } into grouped
// this order makes the whole query ordered(primary sort?)
orderby grouped.Sum(x => x.price) descending
select grouped
;


from sales in File.ReadAllLines(file).Skip(1)
select sales.Split(",") into sales
select (itemName: sales[1], stackSize: sales[2], quantity: decimal.Parse(sales[3]), price: decimal.Parse(sales[4]), otherPlayer: sales[5]) into grouped
// grouping the selection by otherPlayer and itemNames
group grouped by new { grouped.otherPlayer, grouped.itemName } into grouped
// therefore selecting for each player a grouped view where the values
// for quantity and price of each item that appears gets summed
select new
{
grouped.Key.otherPlayer,
item = grouped.Key.itemName,
quant = grouped.Sum(x => x.quantity),
price = grouped.Sum(x => x.price) / 10000
}
into grouped
// here the results for each otherPlayer but not the whole query are getting ordered(secondary sort?)
orderby grouped.price descending
// if i dont group here again, I cant order by the summed values that each player has, why?
group grouped by new { grouped.otherPlayer } into grouped
// this order makes the whole query ordered(primary sort?)
orderby grouped.Sum(x => x.price) descending
select grouped
;
7 Replies
D.Mentia
D.Mentia6mo ago
Don't know if I understand the question or the query... but, grouping by {otherPlayer, itemName} is creating one group for each unique pair of player,item - IE, a single player will have many groups, one for each item. It sounds like you maybe intended to instead create one group for each player? what exactly are you trying to do? Explain in words plz
Mr. Roach
Mr. RoachOP6mo ago
So in the file I open I got i.E the following two rows:
itemName |quantity |price |otherPlayer
Leichtes Leder |40 |7593 |Gekrallt
Leichtes Leder |14 |7593 |Gekrallt
itemName |quantity |price |otherPlayer
Leichtes Leder |40 |7593 |Gekrallt
Leichtes Leder |14 |7593 |Gekrallt
My goal was to sum up the quantity and price values for each similar itemName for each otherPlayer which results into information about how much quantity of an itemName a specific otherPlayer bought and paid for in total - like pivoting the data in some way if that term is fitting here. The query was built by myself and works as intented - i just wanted to ask if I understood the process correctly and or if there is a better way or improvement available. The query outputs for that player, instead of the two example rows(the summes data for the two entries are at the bottom, on top I added the total summed data for all the entries of that otherPlayer found in the file input for the query):
No description
Mr. Roach
Mr. RoachOP6mo ago
Besides from asking about weither i understood the process correctly - in future i want to try to make like a simple file based "database" of sales and costs data with the possibility to search and filter through all that data in customizable ways via wpf application - but thats future stuff, just answered what exactly im trying to do. Here i tried and tested a bit to hopefully get a better grasp of linq and queries
Angius
Angius6mo ago
Just FYI: barely anybody uses the query LINQ syntax, pretty much everything and everyone uses the extension methods
D.Mentia
D.Mentia6mo ago
I see, I think... 1. You're grouping by {otherPlayer, itemName}, resulting in one grouping per unique player/item. This means there are multiple groups for a given otherPlayer 2. You're ordering these groupings by price; I'm not sure the purpose of this, and it probably doesn't need to happen 3. You're grouping the new values by otherPlayer; now you have one grouping per otherPlayer, instead of multiple, and each 'row' in that grouping is quantity, price, etc for a given item sold to otherPlayer 4. You're ordering by the sum of prices; so, otherPlayers that have spent the least on all items are first in the results Everything seems valid except the first order by ah. The first order by is valid too, to ensure that the rows for a player (one for each item) are ordered by price
Mr. Roach
Mr. RoachOP6mo ago
Oh I think I didn't received any notification about your messages, thanks for responding I have yet to figure out why exactly the method expressions are used so much. Years ago I was an apprenticeship and had to work here and there with SQL statements, therefor the query syntax seemed so familiar for the beginning. But when I discovered the dynamic linq library recently I saw that this is used with method syntax aswell, so depending on for what and how I choose to use linq in my project if I come to the conclusion that it makes sense to implement more I would need to get into the method syntax aswell. Thanks for your review. Since I struggled with SQL back then when I was an apprenticeship I wanted to make sure that I produced a somewhat valid query here while understanding it correctly too.
Angius
Angius6mo ago
Method syntax is preferred because the query syntax just... doesn't look like C#. That, and the query syntax is not extendable. You can't write your own Paginate() method that wraps skip and take and use it in query syntax. Not without some ugliness.
Want results from more Discord servers?
Add your server