LINQ仅返回集合中的一项 [英] LINQ only returns one item in collection

查看:89
本文介绍了LINQ仅返回集合中的一项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Project模型,该模型具有分配为ProjectManagers或更常见的Users

I have a Project model that has a collection of AppUsers assigned to be ProjectManagers or the more general case of 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的所有项目的列表,而不管它们是否属于ProjectManagersUsers集合

In my controller, I try to generate a list of all the project a particular AppUser is assigned to, regardless if they are in the ProjectManagers or Users collection

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

但是,如果AppUser涉及多个Project,则只有最后一个Project会填充此列表.如何确保所有关联的项目都被退回?

However, if an AppUser is involved with more than one Project only the last Project populates this list. How do I ensure all associated projects are returned?

我的AppUser模型:

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

在我的控制器中,我使用List动作方法来显示与AppUser相关的所有Projects.这是无法正常工作的部分,仅返回单个Project

In my controller I use the List action method to display all the Projects related to the AppUser. This is the part that isn't working correctly, it's only returning a single 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");
        }

以下方法用于生成列表和分页模型

The following methods are used to generate the lists and the models for pagination

 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;
        }

EDIT 我注意到,当我运行proj.ProjectManagers.Add(appUser);时,它将以ProjectManager的身份添加该用户,但看起来它还将其从先前分配的其他任何项目的ProjectManager集合中删除了

EDIT I noticed when I run proj.ProjectManagers.Add(appUser);, it will add that user as a ProjectManager but it looks like it it also deletes them from the ProjectManager collection of any other project they were previously assigned

推荐答案

问题是我没有使用多对多联合表.因此,当我将AppUser添加到Project时,它删除了任何先前对象之间的关系.因此,只有一个Project将与用户相关联.为了解决这个问题,我创建了该类:

The issue was that I wasn't using a many-to-many joint table. So when I added an AppUser to a Project, it deleted the relationship between any previous objects. Thus, only one Project would be associated with a user. To fix this, I created the class:

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

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

并将此收藏集添加到我的AppUser类中:

and added this collection to my AppUser class:

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

并将以下内容添加到我的dbContext中:

And added the following to my 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

After running a migration and update, a single user can now be associated with more than one Project as a ProjectManager

这篇关于LINQ仅返回集合中的一项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆