0

Let's say I have a list of Student objects and I want to find their tuition. Their tuition is in a database and the key is their student id. I want to map that tuition into the student objects after. So I have

Class Student{
    int Id;
    string Name;
    double GPA;
    double Tuition; 
}

Example Database Tuple would be |Id | Tuition | SchoolName| Student Name|

    List<Double> GetTuitionsById(List<Student> students)
    {
        var ids = students.Select(x => x.Id).ToList();
        var query = from dbStudent in _context.StudentsDB
                    where ids.Contains(dbStudent.Id)
                    select dbStudent.Tuition;

        var tuitions = query.ToList();

        return tuitions;
    }

I was then hoping to loop through tuitions and map it into the students list, but the select query doesn't return the prices in the same order. So how can I map the tuitions from the DB to the student objects?

2 Answers 2

1

When you have no ordering in the database query the results coming from the database are not guaranteed to be in any specific order. To return the results in the order they were passed in you need to return Id from the database so the data can be mapped to initial list and then create the list manually:

List<Double> GetTuitionsById(List<Student> students)
{
    var ids = students.Select(x => x.Id).ToList();
    // return Id and tuition
    var query = from dbStudent in _context.StudentsDB
                where ids.Contains(dbStudent.Id)
                select new { dbStudent.Id, dbStudent.Tuition};  

    var tuitions = query.ToList();

    var results = List<double>();
    foreach(var student in students)
    {
        // below is assumed that every student has tuition returned from the database
        var foundTuition = tuitions.First(t => t.Id == student.Id);
        results.Add(foundTuition.Tuition);
    }
    return results;
}

Edit: @pwas correctly pointed out that using Dictionary would give a better performance:

List<Double> GetTuitionsById(List<Student> students)
{
    var ids = students.Select(x => x.Id).ToList();
    // return Id and tuition
    var query = from dbStudent in _context.StudentsDB
                where ids.Contains(dbStudent.Id)
                select new { dbStudent.Id, dbStudent.Tuition};  

    var tuitions = query.AsEnumerable().ToDictionary(s => s.Id, s => x.Tuition);

    var results = List<double>();
    foreach(var student in students)
    {
        // below is assumed that every student has tuition returned from the database
        results.Add(tuitions[student.Id]);
    }
    return results;
}
Sign up to request clarification or add additional context in comments.

4 Comments

Small improvement / hint: You code works in O(n^2). So you can make tuitions a dictionary: query.AsEnumerable().ToDictionary(s => s.Id, s => x.Tuition). Then, in foreach: var foundTuitions => tuitions[student.Id]. Thanks to this, code will work in 2 * O(n), so it could be faster when many students are in the list ;)
@pwas That's an excellent point! I will update the answer to include this option
Then would not making var ids = students.Select(x => x.Id).ToList();into a dictionary instead also be better then? So we can replace where ids.Contains(dbStudent.Id) to ids.ContainsKey(dbStudent.Id).
@roverred The part of query that you are referring to is executed by Entity Framework, and it does not support dictionary. If you make the changes that you are referring to you would get a runtime exception
0

try .

 List<Double> GetTuitionsById(List<Student> students)
    {
     List<Double> objRes=new List<Double>();
        var ids = students.Select(x => x.Id).ToList();
        var query = (from dbStudent in _context.StudentsDB
                    where ids.Contains(dbStudent.Id)
                    select dbStudent.Tuition).ToLIst();
         foreach(var x in query )
         {
          objRes.Add(Double.Parse(x));
         }

        return objRes;
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.