LINQ возвращает только один элемент в коллекции - PullRequest
0 голосов
/ 22 марта 2019

У меня есть модель Project с коллекцией AppUsers, присвоенной ProjectManagers или более общим случаем Users

public class Project
    {
        public int ProjectID { get; set; }

        [Required(ErrorMessage = " Please enter a project name")]
        public string Name { get; set; }

        public virtual ICollection<AppUser> ProjectManagers { get; set; }

        public virtual ICollection<AppUser> Users { get; set; }
    }

В моем контроллере я пытаюсь сгенерироватьсписок всех проектов, которым назначен конкретный AppUser, независимо от того, находятся ли они в коллекции ProjectManagers или Users

projectList = repository.Projects.Where(p => p.ProjectManagers.Contains(user) || p.Users.Contains(user));

Однако, если AppUser связан с более чемодин Project только последний Project заполняет этот список.Как убедиться, что все связанные проекты возвращены?

Моя AppUser модель:

public class AppUser : IdentityUser
    {
        //literally does nothing at this point and 
        // is merely a placeholder until I add more
    }

В моем контроллере я использую метод действия List, чтобы отобразить все связанные Projectsдо AppUser.Эта часть работает неправильно, она возвращает только один Project

public async Task<IActionResult> List(int page = 1)
        {
            var user = await userManager.FindByNameAsync(User.Identity.Name);
            if(user != null)
            {
                IQueryable<Project> projectList = GetUserProjects(page, user);
                var model = GetProjectsListViewModel(projectList, page, user);
                return View(model);
            }
            TempData["message"] = "User not found";
            return RedirectToAction("Index", "Home");
        }

Следующие методы используются для генерации списков и моделей для разбивки на страницы

 public ProjectsListViewModel GetProjectsListViewModel (IQueryable<Project> projectList, int page, AppUser user)
        {
            ProjectsListViewModel model = new ProjectsListViewModel();
            model.Projects = projectList
                    .OrderBy(p => p.ProjectID)
                    .Skip((page - 1) * PageSize)
                    .Take(PageSize);
            model.PagingInfo = new PagingInfo
            {
                CurrentPage = page,
                ItemsPerPage = PageSize,
                TotalItems = projectList.Count()
            };
            return model;
        }

        public IQueryable<Project> GetUserProjects(int page, AppUser user)
        {
            IQueryable<Project> projectList;
            //IQueryable<Project> result;
            if (user.UserName == "Admin")
            {
                projectList = repository.Projects;
            }
            else
            {

               projectList = repository.Projects
                .Where(p => p.ProjectManagers.Any(pm => pm.Id == user.Id) || p.Users.Any(u => u.Id == user.Id))
                .Select(x => new { UserId = user.Id, Projects = x })
                .GroupBy(p => p.UserId)
                .Select(x => x.OrderByDescending(p => p.Projects.ProjectID).First().Projects);

                //None of the commented out code works either
                //projectList = repository.Projects.Where(p => p.ProjectManagers.Contains(user) || p.Users.Contains(user) || p.CommissioningAuthorities.Contains(user));

                //foreach (Project p in repository.Projects)
                //{
                //    if(p.ProjectManagers.Contains(user) || p.Users.Contains(user) || p.CommissioningAuthorities.Contains(user))
                //    {
                //        projectList.ToList().Add(p);
                //    }

                //}
            }
            return projectList;
        }

РЕДАКТИРОВАТЬ Я заметил, что когда я запускаю proj.ProjectManagers.Add(appUser);, он добавляет этого пользователя как ProjectManager, но, похоже, он также удаляет их из коллекции ProjectManager любогодругой проект им был ранее присвоен

Ответы [ 2 ]

0 голосов
/ 26 марта 2019

Проблема заключалась в том, что я не использовал общий стол "многие ко многим".Поэтому, когда я добавил AppUser к Project, он удалил связь между любыми предыдущими объектами.Таким образом, только один Project будет связан с пользователем.Чтобы это исправить, я создал класс:

public class ProjectManager
{
    public int ProjectID { get; set; }
    public Project Project { get; set; }

    public string AppUserID { get; set; }
    public AppUser AppUser { get; set; }
}

и добавил эту коллекцию в свой класс AppUser:

    public class AppUser : IdentityUser
    {
        public ICollection<ProjectManager> ProjectsAsManager { get; set; }
    }

И добавил следующее в свой dbContext:

            modelBuilder.Entity<ProjectManager>()
                .HasKey(ppm => new { ppm.ProjectID, ppm.AppUserID });

            modelBuilder.Entity<ProjectManager>()
                .HasOne(pm => pm.AppUser)
                .WithMany(p => p.ProjectsAsManager)
                .HasForeignKey(pm => pm.AppUserID);

            modelBuilder.Entity<ProjectManager>()
                .HasOne(pm => pm.Project)
                .WithMany(p => p.ProjectManagers)
                .HasForeignKey(pm => pm.ProjectID);

            base.OnModelCreating(modelBuilder);

После запуска миграции и обновления один пользователь теперь может быть связан с более чем одним Project как ProjectManager

0 голосов
/ 22 марта 2019

Здесь, поскольку в вашем проекте нет даты и времени, я предполагаю, что проект с большим Id является более новым:

var result = Projects
    .Where(p => p.ProjectManagers.Any(pm => pm.Id == user.Id)
           || p.Users.Any(u => u.Id == user.Id))
    .Select(x => new { UserId = user.Id, Projects = x })
    .GroupBy(p => p.UserId)
    .Select(x => x.OrderByDescending(p => p.Projects.ProjectID).First().Project);

Чтобы получить все проекты пользователя:

var result = Projects
    .Where(p => p.ProjectManagers.Any(pm => pm.Id == user.Id)
           || p.Users.Any(u => u.Id == user.Id));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...