Linq Conversion From ICollection<T> to List<T>

Hassaan picture Hassaan · Jul 2, 2014 · Viewed 12.4k times · Source

I am using Code First Entity Framework.

I am using the following simple classes:

public class Users
{
    public ICollection<Projects> Projects{get;set;}
}

public class Projects
{
    public ICollection<Users> Users{get;set;}
}

I am using linq for data retrieval. When performing the following query: (Note that lstProjects is a List<Project>)

var lstUsers = (from users in lstProjects
                where users.ProjectId == pId
                select users.Users).ToList();

I have a List<Users> object and want to populate this List with items. Like,

var lstUsersToDisplay = new List<Users>();
lstUsersToDisplay = (List<Users>)lstUsers; //This can't be cast.

What's the approach to convert ICollection<T> to List<T>?

Secondly, I have List<Users> and want to convert it into ICollection<Users> how achieve this?

Edited: Scenario, more clearly is that All Projects are loaded in lstProjects and we need to select the Users which were mapped to a specific project. These Users are also are contained inside Projects as collection. Every Project has its Users collection like if I decomposed the lstProjects it would be like:

lstProjects --> [0]-->//other Properties ICollection[Users]-->[0]//Contains User class Properties [1].... [1] ... same procedure

Hope it clears the scenario

Answer

Jon Skeet picture Jon Skeet · Jul 2, 2014

If your query is genuinely this:

var lstUsers = (from users in lstProjects
                where users.ProjectId == pId
                select users.Users).ToList();

then that's equivalent to:

List<ICollection<Users>> lstUsers = (from users in lstProjects
                                     where users.ProjectId == pId
                                     select users.Users).ToList();

If you're trying to get the list of uses from a single project, I'd write that as:

var lstUsers = lstProjects.Single(project => project.ProjectId == pId)
                          .Users
                          .ToList();

If there could be multiple projects with the same ProjectId, you want to flatten the users. For example:

var lstUsers = lstProjects.Where(project => project.ProjectId == pId)
                          .SelectMany(project => project.Users)
                          .ToList();

Or in query expression syntax:

var lstUsers = (from project in lstProjects
                where project.ProjectId == pId
                from user in project.Users
                select user).ToList();

Note the fact that my range variable is called project, because it refers to a project, not a user. Naming is important - pay attention to it. I would also rename the Projects and Users types to just Project and User, assuming each is really only meant to represent a single entity.