tags:

views:

478

answers:

1

I'm not sure if an answer for this already exists, as I can't figure out what mechanism in Linq is meant for this situation, or if I just need to do it manually.

Let's say I have 2 tables:

------------Employees-------------
EmployeeID  Name  -other columns-

   ---------EmployeeSkills-----------
   EmployeeID  Skill  -other columns-

So each employee can have 0 or more skills.

My goal is to draw this information into a data structure in memory, using one sql query

    class StaticEmployee
    {
        int EmployeeID;       
        string Name;
        List<string> Skills;
    }
    List<StaticEmployee> employees = (???).ToList();

Since my table relations are setup, I could just foreach the employees table (from employee in db.Employees select employee), however when I access the EmployeeSkills property, it is going to execute a seperate query for every employee record since that data wasn't returned with the first query.

Alternatively, and I what I want done so far as Sql is concerned, is run a query with a left join:

SELECT Employees.EmployeeID, Employees.Name, EmployeeSkills.Skill FROM Employees LEFT JOIN EmployeeSkills ON Employees.EmployeeID=EmployeeSkills.EmployeeID

That will get me my list, but I'll need to manually collate it into my list since an employee with 2 skills will return 2 rows. Is there a Linq operation that does this? Hypothetical example below

from employee in db.Employees
select new 
{
   EmployeeID = employee.EmployeeID, 
   Name = employee.Name,
   Skills = new List(
                     from employeeSkill in employee.EmployeeSkills 
                     select employeeSkill.skill
                    )
}
+3  A: 
var options = new DataLoadOptions();
options.LoadWith< Employees>(e => e.EmployeeSkills);
context.LoadOptions = options;
//retrieve employees, they will come loaded with EmployeeSkills

If you were to use the linq query version instead, this will load them once as well:

from employee in db.Employees
select new 
{
   EmployeeID = employee.EmployeeID, 
   Name = employee.Name,
   Skills = employee.EmployeeSkills
}
eglasius
This looks good - even better, LoadWith provides me with a feature I didn't know existed. Upvoted.To finalize this, is there a way (in the second method) to only return some of the columns from EmployeeSkills (I only want/need the Skill column, not every column in that table)
David
Nevermind, I just tried the obvious and changed "Skills = employee.EmployeeSkills" to "Skills = employee.EmployeeSkills.Select(s=>Skill)". Marked answered.
David
As a side note, LoadOptions need to be specified as the first thing in the datacontext, that can be a pain sometimes. Also as you noticed, it loads the whole info, which is not always what you need. I go the linq query for most, only loadoptions if I need to update.
eglasius