I have a simple scenario for which i want to write LINQ query, But i am unable to get it right. Here is the scenario:
I have 3 Tables:
STUDENT:
--------------------------
SID Name
---------------------
1 Jhon
2 Mishi
3 Cook
4 Steven
COURSE:
-------------------
CID Name
-------------------
1 Maths
2 Physics
3 Bio
4 CS
STUDENTCOURSE:
---------------------------
SCID SID CID
-----------------------
1 1 1
2 1 2
3 1 4
4 2 1
5 2 2
6 2 3
7 3 1
8 3 4
10 4 2
For this case i want to pass array of course ids to query and return all student those have all the these courses registered against them. What i tried:
int[] cIds = {1,2,4 };
var result = from s in context.Students
where s.StudentCourses.Any(sc=> cIds.Contains(sc.CID))
select s;
But this returns students those registered either of the course id 1,2,4. Hope you understand my problem.
Thanks for the help.
Use this:
int[] cIds = {1,2,4 };
var q = context.StudentCourses.Join(context.Students,
x => x.SId,
x => x.Id,
(sc, s) => new { Student = s, CourseId = sc.CId })
.GroupBy(x => x.Student.Id)
.Where(sc => cIds.All(cid => sc.Any(y => y.CourseId == cid)))
.Select(x => x.FirstOrDefault().Student)
.ToList();
Or if you prefer linq query:
int[] cIds = {1,2,4 };
var q2 = (from s in context.Students
join sc in context.StudentCourses on s.Id equals sc.SId into sCources
where cIds.All(id => sCources.Any(y => y.CId == id))
select s).ToList();
Here is a fiddle for it, using linq-to-objects.
Edit:
I didn't notice that in your model there is a navigation property from Student
to StudentCourse
, in this case the query will be much simpler and does not need join, and Patrick's answer works perfectly.
Try the following:
int[] cIds = {1,2,4 };
var result = from s in context.Students
where cIds.All(id => s.StudentCourses.Any(sc=> sc.CID == id))
select s;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.