Multiple OrderBy not ordering correctly [duplicate] - c#

This question already has answers here:
Multiple "order by" in LINQ
(7 answers)
Closed 3 years ago.
I'm trying to order by WeekId, then Order in my SQL table (end result should have workouts together by id, then ordered by the order specified), yet it is giving the wrong order. Is there something wrong with my LINQ statement?
private List<Workout> GetWorkouts(int id)
{
return new OPPDBContext().Workouts
.Where(p=>p.ClientId == id).OrderBy(p => p.Order).OrderBy(p => p.WeekId).ToList();
}
The table:
The results:
Expected results:
Lat Pulldowns
Squats
Lat Pulldowns
Squats
Reverse Lunges

That's because the second .OrderBy replaces the first .OrderBy (you are sorting by ClientId, and then effectively discard that to sort by WeekId).
You need to use .OrderBy(...).ThenBy(...) instead:
return new OPPDBContext().Workouts.Where(p=>p.ClientId == id).OrderBy(p => p.Order).ThenBy(p => p.WeekId).ToList();
OrderBy docs
ThenBy docs

Related

Extracting a list from a list LINQ [duplicate]

This question already has answers here:
Using LINQ, select list of objects inside another list of objects
(2 answers)
Closed 1 year ago.
I am trying to extract a list of Goals from within a list of Students using this method
public List<Goal> GetGoalsForTeacher(int userId)
{
var students = GetStudentsForTeacher(userId);
var result = students.Select(e => e.Goals).ToList();
return result
}
However, I need it to return a List, but it is returning a List<IList>. Has anyone any idea on how I would convert this or make it a List initially?
You're looking for the SelectMany() method.
var result = students.SelectMany(e => e.Goals).ToList();

How many times will Linq to Objects iterate over a source? [duplicate]

This question already has answers here:
What are the benefits of a Deferred Execution in LINQ?
(3 answers)
What do they mean when they say LINQ is composable?
(2 answers)
Numbers of iteration generated in a single LINQ query
(1 answer)
Closed 3 years ago.
Say I have a simple Linq query:
var x = words.Where(w => w.Length > 4).Select(w => w.ToUpper()).ToArray();
Will the compiler generate code that iterates over words once, filtering and transforming as it goes, or code that generates an intermediate enumeration and then iterates over that?
What if there's an OrderBy():
var x = words.Where(w => w.Length > 4).OrderBy(w => w).Select(w => w.ToUpper()).ToArray();
I could see the compiler either iterating once over words, filtering and uppercasing words as it goes and merging them into an already sorted IOrderedEnumerable, or I could see it generating an intermediate array, sorting that, and then transforming it.
Rewrite the query as follows to see the flow of the data.
var x = words
.Where(w =>
{
Console.WriteLine("Where: " + w);
return w.Length > 4;
})
.Select(w =>
{
Console.WriteLine("Select: " + w);
return w.ToUpper();
})
.ToArray();

IN condition in LINQ to replace multiple OR conditions [duplicate]

This question already has answers here:
Linq to SQL how to do "where [column] in (list of values)"
(6 answers)
Closed 6 years ago.
I have an entity framework query as shown below. Here I am trying to find entities for which there is no fax information for primary and secondary users. I am using two person_role_cd conditions using “OR”.
What is the best LINQ way to make the same logic with something like SQL “IN” condition? For example, p.person_role_cd IN (“Primary”, “Secondary” )
query = query
.Where(l => l.loan_documents
.FirstOrDefault(d => d.document_type_cd == “Application”)
.loan_persons.Any(p =>
(
p.fax_no != null
&&
(
p.person_role_cd == “Primary”
||
p.person_role_cd == “Secondary”
)
)
) == false
);
First create an array with all strings you want to check against.
var targetList = new[] {"Primary", "Secondary"};
Then Replace your OR condition with
targetList.Contains(p.person_role_cd);
Caveat: Doing stuff like this causes problems with Linq to Entities
That said, the first thing that comes to mind is use a List with Contains (which is basically what the provided SQL does)
List<string> roles = new List<string>() { "Primary", "Secondary" };
query = query
.Where(l => l.loan_documents
.FirstOrDefault(d => d.document_type_cd == “Application”)
.loan_persons.Any(p => p.fax_no != null && roles.Contains(p.person_role_cd));
Couldn't quite tell where your negation belongs, left as exercise to the reader. The reason it may not work with Linq to Entities is that translating List.Contains (especially off of a local variable) to SQL is the kind of task it likes to give up on. If your types are literally two items, I would just keep the condition as is (apart from considering an enum for my types instead of strings)

Mimic SQL IN Clause with LINQ [duplicate]

This question already has answers here:
Where IN clause in LINQ [duplicate]
(8 answers)
Linq to Entities - SQL "IN" clause
(9 answers)
Closed 8 years ago.
I am trying to mimic an IN() clause commonly used in SQL and use it in my LINQ statement.
I see that there is an overload for Contains() that takes an IEnumerable collection. I have tried passing in ILIST and Dictionary but neither is correct.
How do I accomplish this?
Thanks, much appreciated.
SQL
select
oec.OnlineEducationCourseId,
oec.CourseTitle,COUNT(oec.CourseTitle) as CourseCount
from OnlineEducationRegistration as oer
join OnlineEducationCourse oec on oec.OnlineEducationCourseId = oer.OnlineEducationCourseId
where oer.ClubId IN('K20','B67','P89')
and DateCompleted between '2013-01-01' and '2014-01-01'
group by oec.CourseTitle,oec.OnlineEducationCourseId
Same SQL query in LINQ
var r = (from oer in db.OnlineEducationRegistrations
join oec in db.OnlineEducationCourses on oer.OnlineEducationCourseId equals
oec.OnlineEducationCourseId
where (oer.ClubId.Contains(some IEnumerable collection here) && oer.DateCompleted >= start.Date && oer.DateCompleted <= end.Date)
group new { oec, oer } by new { oec.CourseTitle, oec.OnlineEducationCourseId }).ToList();

Linq to Entities "does not recognize the method ... method, and this method cannot be translated into a store expression." [duplicate]

This question already has an answer here:
Method cannot be translated into a store expression
(1 answer)
Closed 9 years ago.
I have a problem. I create a Data Entity Model in Visual Studio. And in Linq;
Guid RtuDataId = db.RtuData.Where(x => x.CommunicationUnit.Id == new Guid(ID))
.OrderByDescending(x => x.ReadOn)
.LastOrDefault().Id;
I get error ;
does not recognize the method ... method, and this method cannot be translated into a store expression.
I searched in Google but I don't understand this error.
Its LastOrDefault which is not supported in LINQ to Entites. I am not sure why you are using OrderByDescending, instead you can use OrderBy and then select First. Also its better if you create new Guid before your query and then pass it to your where clause like:
var guid = new Guid(ID);
Guid RtuDataId = db.RtuData
.Where(x => x.CommunicationUnit.Id == guid)
.OrderBy(x => x.ReadOn)
.FirstOrDefault()
.Id;
Since FirstOrDefault may return null, so you should check for null before accessing Id

Categories