#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>
aslstUsers
, несмотря на ваши имена. Если вы наведете курсор наvar
ofvar 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();