Meaning of OrderBy(x => 1) in C# LINQ - c#

I encountered a linq expression that goes something like this:
var result = someCollection.Where(some_filter_condition).OrderBy(x => 1).ToList();
I'm wondering what's the purpose of the lambda expression x => 1 in the OrderBy linq method?

It seems pretty meaningless to me. It's going to "sort" the sequence, but instead of basing the sort order on a property of each element, it's going to use the key 1 for every element. This would be the same as not sorting at all.
I would guess that this was a placeholder that someone meant to go back and implement, but never did.

It is possible that some method would require input of type IOrderedQuery, so in order to convert it to required type, user might have added this lambda.

Related

Sorting by count of matching related data Linq, ThenBy doesnt work

I wrote a query that sorts the result based on the amount of matching elements of a given list. This works when using a single OrderBy.
However, since I want to use Pagination, I need to use a ThenBy to make sure the order is always the same.
The current query somehow moves the subquery inside the OrderBy/ThenBy and can't be translated.
How can I re-write this query so that ThenBy would work?
Thanks.
Code:
products
.Select(product => new ProductDto(product)
{
MatchingContainsCount = (from contain in product.Contains
where allergens.Contains(contain.Allergen.Name)
select contain.Allergen).Count(),
MatchingMayContainCount = (from mayContain in product.MayContain
where allergens.Contains(mayContain.Allergen.Name)
select mayContain.Allergen).Count()
})
.OrderBy(dto => dto.MatchingContainsCount)
.ThenBy(dto => dto.Id); // Without this line it works
The Translation error:
Instead assigning Id property inside the constructor, assign the Id property and other properties within the PropertyDto body, similar to MatchingContainsCount property. EF core doesn't translate complex property assignment within the class constructor or methods to SQL. Only the simple assignments. This should fix the problem.

Querying across relationships with LINQ to Entity Framework

Here is what my model looks like:
I'm trying to get the count of distinct Assesors by a certain EventId.
Here's the code I'm trying to use:
var x = db.Assessors.Select(a => (a.Assessments.Select(y => y.EventFacility.EventId == 138))).Count();
Unfortunately, I must be coding this wrong because instead of getting the expected result (a count of 9, in this case) I'm getting the wrong result: 35.
I'm wondering if someone can take a look at my LINQ statement and tell me what I'm doing wrong?
You need to use Where and Any like this:
var result = db.Assessors
.Where(a => a.Assessments.Any(y => y.EventFacility.EventId == 138));
What this is saying is that you want all Assessors that are parents of any Assessment that is related to that particular Event.
You're going about this backward, start from what you know (the event since you have it's ID) and navigate to what you want through the navigation properties.
It's impossible to tell from your schema as it includes neither the properties nor the mapping type 1:1? 1:N? Can't know from simple lines
It would probably look Something like this
var x = db.Events
.Where(ev=>ev.Id == 138)
.SelectMany(ev=>ev.EventFacilities) //(i'm assumine possibly multiple and not 1 per event, once again schema doesn't show it, if it's not the case change SelectMany to Select)
.SelectMany(ef=>ef.Assesments) // Same assumption as above
.Select(as=>as.Assessor) // Asuming otherwise here, if wrong change Select to SelectMany
.Distinct(); // Ignore duplicate assessors
Note that your question is impossible to answer as is, this is a best effort but if you want help you should give "all" the information required, not strip out what doesn't immediately seem relevant, it would've been much easier if you took an actual screenshot of your entity diagram instead of what you made up.

How to use Orderby Clause with IEnumerable

I have written following code:
IEnumerable<Models.bookings> search = new List<bookings>();
search = new available_slotsRepositories().GetAvailableSlot(param1,param2);
var data = from s in search.AsEnumerable().
OrderByDescending(c => c.BookingDate)
select s;
i have also tried this and it does not work:
search.OrderByDescending(c => c.BookingDate);
Third line gives me following error:
Expression cannot contain lambda expressions
Any one guide me how can i fix this issue?
Any help would be appreciated.
Thank you!
why r u using new List()??
follow the below pattern
IEnumerable<Step> steps = allsteps.Where(step => step.X <= Y);
steps = steps.OrderBy(step => step.X);
NOTE:
IEnumerable makes no guarantees about ordering, but the implementations that use IEnumerable may or may not guarantee ordering.
For instance, if you enumerate List, order is guaranteed, but if you enumerate HashSet no such guarantee is provided, yet both will be enumerated using the IEnumerable interface
Perhaps you are looking for the IOrderedEnumerable interface? It is returned by extensions methods like OrderBy() and allow for subsequent sorting with ThenBy().
Have you tried
var data = (from s in search
OrderByDescending(c => c.BookingDate)
select s).ToList();
That will make a List which is IEnumerable.
I'm not sure why you need "new" if as you say GetAvailableSlot returns an IEnumerable. What I think your code should look like assuming GetAvailableSlot returns IEnumerable is this:
var data = available_slotsRepositories().GetAvailableSlot(param1,param2).ToList().OrderByDescending(c => c.BookingDate);
All you're doing to your recordset is ordering the results there is no need to have multiple variables declared. If this still doesn't work then we need to see more of the code in order to see what the problem is...

Dynamically adding select fields using LINQ lambda

Lets say we have an expression:
var prices = from p in PriceDB.Prices
where p.TypeID == 12
orderby p.PriceType.Title
select p;
Is it possible to modify the select list?
I imagine it looking something like this:
var newPriceList = prices.Select( p => p.ExchangeRate );
This may be an odd request, but in my code (which is too long and complex to post here) I want to conditionally add fields to be output depending on a CheckBoxList.
I assume, of course, that I'm trying to go about this the wrong way...
I imagine it looking something like this:
Actually it would look exactly like that. First, build a query, selecting the entire record. Then add a select (using the Select() method seem the easiest way) to limit the selection. Linq-to-Sql will sort out the two selects, and use the proper reselt, so theres just one select in the final SQL.
There's no really good way to choose between multiple selects. I would probably use a switch/case.
While you could go down the dynamic route, I would strongly consider not doing so. What is the cost of fetching the extra values if you don't need them, in your particular case? Is the problem that they're being displayed dynamically and you only want them displayed in certain cases? If so, I'd suggest modifying the display code somehow.
It's hard to stay strongly typed (which has various advantages) while being dynamic in terms of what you fetch. Of course, if you always want to fetch the same "shape" of data (e.g. always just a decimal value from each row) then that's reasonably easy - let me know if that's something you'd like to see demonstrated.
If you could tell us more about your problem, we may be able to suggest alternative solutions.
If I understood you correct this is explaining how to build dynamic queries:
http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
You might want to look at this Dynamic LINQ and Dynamic Lambda expressions?
Or the Dynamic Expression API (System.Linq.Dynamic).

LINQ: Help with linq query and contains for an IEnumerable<string>?

Can anyone help?
I have a linq query which is embedded inside a extension method, it was working as v.RentalStatus was a String. I am now using a Group on my original query (the query is quite complex so i won't put it here).
The importante thing is that v.RentalStatus = IEnumerable hence it can contain things like
A (meaning active)
R (meaning rented)
U (unavailable)
etc - many more
I create a list of what i would like to get back and store this in statusStringList, so for example lets say the list contains A and R
This is my code from before when the v.RentalStatus was just a string, can anyone tell me how i can modify this to work.
var statusStringList = rentalStatus.ToList().ConvertAll<string>(st => st.GetStringValue());
return from v in qry
where statusStringList.Contains(v.RentalStatus)
select v;
If it helps this is part of my query which returns the RentalStatus - its part of a group query but the RentalStatus is not in the group by
RentalStatus= g1.Select( j => j.IdRentalStatus).Distinct(),
g1 is my group by, so if you imagine there are 10 "A", 5 "U" .. then it would return an ienumerable of A and U ... as i am using Distinct. Not 10 As and 5 Us
I hope i have explained it well, please tell me if i haven't
I would appreciate any help from anyone ..
thanks
EDIT
This is my extension signature but not that it matters.
public static IQueryable<Rentals> WithStatus(this IQueryable<Rentals> qry, IList<Contants.Statuses> rentalStatus)
{
EDIT
As mentioned previously when v.RentalStatus was a string it was working but now its IEnumerable - hence a collection.. and it errors with this
Argument '1': cannot convert from 'System.Collections.Generic.IEnumerable<string>' to 'string'
If RentalStatus has changed from a string to a IEnumerable<string> then your comparing 2 list... I think this should work:
return from v in qry
where v.RentalStatus.Any(status => statusStringList.Contains(status))
select v;
This should give you any rentals that have a status that is in the list you are providing
Edit:
Yeah I would spend some time learn lambda expressions. Seems like they are being used more and more and with good reason. Here are a few links for tutorials:
An Extensive Examination of LINQ: Lambda Expressions and Anonymous Types
.NET Lambda Expressions – Resources
"WHERE" RentalStatus = Containing any
of itself - arrgghh -
Is that true? I thought the list of rentalStatuses is a parameter in your method. I was thinking your query basically would allow me to get all the rentals that have a status that matches any of the list that I specified. One list lives on your Rental object and the other is the one I pass in...
As to why the order in mine worked. I have some questions:
Are you using this to query a database? Are you able to look at the tsql it generates?
If so, I would look at the tsql and see what the difference is. I would have to check myself. I got lucky I guess.
You could try something like this:
where statusStringList.Any(x => v.RentalStatus.Contains(x))
I am not sure but I think that for a Contains to work in Linq to SQL it must be an array of strings (or ints or ...) and not any IEnumerable. I would thus try:
var statusStringArray = rentalStatus.ToList().ConvertAll<string>(st => st.GetStringValue()).ToArray();
return from v in qry
where statusStringArray.Contains(v.RentalStatus)
select v;
There might be other issues though, I did not look that much.
Try this:
return from v in qry
where rentalStatus.Any( r => r.IdRentalStatus == v.RentalStatus)
select v;

Categories