I have the following method signature:
internal static int[] GetStudentIDsThatAreNotLinked(PrimaryKeyDataV1[]
existingStudents, IQueryable<Student> linkedStudents)
PrimaryKeyData is a class that has ServerID and LocalID integers as properties. Student is a class that (among other properties) has an integer one called StudentID.
In English, what I want to do is return an array of integers which are in existingStudents[...].ServerID but not in linkedStudents[...].StudentID
If 'existingStudents' and 'linkedStudents' were both integer arrays, I would use a linq query as below:
return from es in existingStudents where
!linkedStudents.Contains<int>(es) select es;
..which could then be converted to an array of ints.
What I want to do is give Contains an IEqualityOperator that will consider a PrimaryKeyData class to be equal to a Student class if PrimaryKeyData.ServerID == Student.StudentID
So I think I need a lambda expression but I'm very confused on how that would be constructed.
I think I'm going in the right direction but can anyone help me over the final hurdle?
So, my understanding is that you want to get all instances of PrimaryKeyDataV1 whose ServerID property doesn't exist in any of the students.StudentID property of the linkedStudents parameter?
internal static PrimaryKeyDataV1[] GetStudentsThatAreNotLinked(PrimaryKeyDataV1[] existingStudents, IQueryable<Student> linkedStudents)
{
var results = existingStudents.Select(s => s.ServerID)
.Except(linkedStudents.Select(link => link.StudentID))
.ToArray();
return existingStudents.Where(stud => results.Contains(stud.ServerID));
}
Or if you just want an array of IDs...
internal static int[] GetStudentIDsThatAreNotLinked(PrimaryKeyDataV1[] existingStudents, IQueryable<Student> linkedStudents)
{
return existingStudents.Select(s => s.ServerID)
.Except(linkedStudents.Select(link => link.StudentID))
.ToArray();
}
If you only need to return the IDs, you can use something like:
existingStudents.Select(es => es.StudentID)
.Except(linkedStudents.Select(ls => ls.ServerID));
You can write this in query comprehension form, but I think it's less clear:
var result = (from es in existingStudents select es.StudentID);
.Except
(from ls in linkedStudents select ls.ServerID)
If you need to return the result as an array, just use the .ToArray()
extension:
existingStudents.Select(es => es.StudentID)
.Except(linkedStudents.Select(ls => ls.ServerID)).ToArray();
You don't need to create your own equality comparer in the case that you only need to return the set difference in IDs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With