首页 > 解决方案 > LINQ 只返回集合中的一项

问题描述

我有一个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分配给特定项目的所有项目的列表,无论它们是否在ProjectManagersorUsers集合中

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

但是,如果 anAppUser涉及多个,则Project只有最后一个会Project填充此列表。如何确保返回所有相关项目?

我的AppUser模型:

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

在我的控制器中,我使用Listaction 方法来显示所有ProjectsAppUser. 这是无法正常工作的部分,它只返回一个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);,它会将该用户添加为 aProjectManager,但看起来它也会从ProjectManager之前分配的任何其他项目的集合中

标签: c#linqasp.net-core

解决方案


在这里,由于您的项目类中没有日期时间,我假设具有较大 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));

推荐阅读