Преобразование Linq из ICollection в List

#c# #linq #entity-framework #linq-to-entities #icollection

#c# #linq #entity-framework #linq-к-сущностям #icollection

Вопрос:

Я использую Code First Entity Framework.

Я использую следующие простые классы:

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

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

Я использую linq для извлечения данных. При выполнении следующего запроса: (Обратите внимание, что lstProjects это List<Project> )

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

У меня есть List<Users> объект, и я хочу заполнить этот список элементами. Нравится,

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

В ICollection<T> какой List<T> способ преобразовать?

Во-вторых, у меня есть List<Users> и я хочу преобразовать его в ICollection<Users> как этого добиться?

Отредактированный: Сценарий, более очевидно, что все Projects загружены в lstProjects , и нам нужно выбрать те Users , которые были сопоставлены с конкретным проектом. Эти пользователи также содержатся внутри Projects как коллекция. У каждого Project есть свое Users collection подобие, если бы я разложил lstProjects, это было бы похоже:

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

Надеюсь, это очистит сценарий

Комментарии:

1. Что такое lstProjects ? Если это a, List<Project> то у вас действительно есть List<Project> as lstUsers , несмотря на ваши имена. Если вы наведете курсор на var of var lstUsers в Visual Studio, что это вам покажет? И что это за сообщение об ошибке? Было бы действительно полезно, если бы вы показали короткую, но полную программу, демонстрирующую проблему. (Кроме того, почему вы создаете пустой список, а затем игнорируете его? Почему вы просто не используете var lstUsersToDisplay = lstUsers; ?)

2. @JonSkeet прошу прощения за ввод текста, в основном я извлекаю коллекцию пользователей из списка проектов. я изменил его

3. Так ваша users переменная диапазона на самом деле является Project ? Святое запутанное именование, Бэтмен! Похоже, теперь у вас есть List<ICollection<Users>> . Опять же, вы должны навести курсор на var , чтобы увидеть, что у вас на самом деле есть…

Ответ №1:

Если ваш запрос действительно такой:

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

тогда это эквивалентно:

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

Если вы пытаетесь получить список использований из одного проекта, я бы записал это как:

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

Если может быть несколько проектов с одним и тем же ProjectId , вы хотите сгладить пользователей. Например:

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

Или в синтаксисе выражения запроса:

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

Обратите внимание на тот факт, что моя переменная range вызывается project , потому что она ссылается на проект, не на пользователя. Именование важно — обратите на это внимание. Я бы также переименовал типы Projects и Users просто в Project и User , предполагая, что каждый из них действительно предназначен только для представления одной сущности.

Комментарии:

1. Должно ли быть ГДЕ в «Или в синтаксисе выражения запроса»?

2. приятно — но почему бы вам не использовать перегрузку для .Sinlge этих фильтров также в вашем 3-м фрагменте? Это выглядит приятнее и более читаемо, ИМХО?

3. @bdimag: Действительно, да. Исправит.

Ответ №2:

lstUsers не является List<User> . Это List<ICollection<User>> . Вы сопоставляете каждый проект с последовательностью пользователей, а не с одним пользователем. Чтобы преобразовать коллекцию коллекций в просто набор внутренних элементов, которые вы бы использовали SelectMany , или, в синтаксисе запроса, вы бы написали свой запрос следующим образом:

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

Теперь у вас есть List<User> для lstUsers . Вы можете присвоить это как есть List<User> или an ICollection<User>

Ответ №3:

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