Hassaan
Hassaan

Reputation: 3991

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

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

Upvotes: 2

Views: 14443

Answers (3)

elpezganzo
elpezganzo

Reputation: 367

using System.Linq; //include extension method OfType<> for ICollection
...
List<Projects> userList = lstUsers.OfType<Projects>().ToList();

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1499790

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.

Upvotes: 5

Servy
Servy

Reputation: 203802

lstUsers isn't a List<User>. It's a List<ICollection<User>>. You map each project to a sequence of users, not to a single user. To flatten a collection of collections into just a collection of the inner items you would use SelectMany, or, in query syntax, you'd write out your query like so:

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

Now you have a List<User> for lstUsers. You can assign that as is to a List<User> or an ICollection<User>

Upvotes: 0

Related Questions