I find this an interesting question because while you can use Linq (as shown at the end, here) to create queries from the Classes the OP describes, I think the Linq required is complex, far too complex. There's an easier, and, imho, better way: change the Classes' structure.
By adding a List of SkillID's to the basic 'User Class, you will make queries so much simpler. Here's an example:
public class User
{
public int ID { set; get; }
public string UserName { set; get; }
public List<int> UserSkills { set; get; }
public User(int id, string name, params int[] skills)
{
ID = id;
UserName = name;
UserSkills = new List<int>(skills);
}
public void AddSkill(int skillid)
{
if (!UserSkills.Contains(skillid)) UserSkills.Add(skillid);
}
}</int></int>
Then, it becomes very easy to query on different attributes:
List<user> usersWithSkillsOneAndTwo = uList.Where(usr => usr.UserSkills.Contains(1) && usr.UserSkills.Contains(2)).ToList();</user>
Compare the above with this example of using Linq with the Class structures the OP is (maybe) using now:
<pre lang="C#">public class Users
{
public int ID { set; get; }
}
public class User : Users
{
public string UserName { set; get; }
public User(int id, string name)
{
ID = id;
UserName = name;
}
}
public class SkilledUser : Users
{
public int SkillID { set; get; }
public SkilledUser(int id, int skillid)
{
ID = id;
SkillID = skillid;
}
}
Assuming: a List<User> 'uList; and, a List<SkilledUser 'suList: you could construct a Dictionary<int, List<int>> to map Users to SkilledUsers:
Dictionary<int, List<int>> SkillsByUsers = uList.ToDictionary
(
uitm => uitm.ID,
uitm => suList
.Where(suitm => suitm.ID == uitm.ID)
.Select(suid => suid.SkillID)
.ToList()
);
List<User> UsersWithSkillsOneAndTwo = SkillsByUsers
.Where
(suitm => suitm.Value.Contains(1) && suitm.Value.Contains(2))
.Select(kvpitm => new
{ itm = uList.First(uitm => uitm.ID == kvpitm.Key)})
.Select(aitm => aitm.itm)
.ToList();
Perhaps someone will come along here and replace this Linq with a blindingly simple version :)