【发布时间】:2019-03-22 01:49:31
【问题描述】:
我有一个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 操作方法来显示与AppUser 相关的所有Projects。这是无法正常工作的部分,它只返回一个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 集合中删除它们
【问题讨论】:
-
AppUser是否覆盖GetHashCode和Equals?如果不是,您在两个项目中是否有完全相同的参考?因为如果您不覆盖Equals和GetHashCode,那么它将执行引用相等,并且仅匹配完全相同的对象,而不匹配具有等效值的对象。 -
@juharr 他们需要被覆盖做什么?这是我还没有实现的东西,也不太清楚如何开始。现在
AppUser扩展IdentityUser但我没有添加任何其他属性 -
这取决于您在
AppUser中的内容。假设您想在Name属性上进行匹配,那么您可以让Equals比较名称,GetHashCode只会返回Name.GetHashCode。 -
实际上,如果这是 EF,那么您只需要更改代码以匹配 Ashkan 在他的答案中的任何 PK。
标签: c# linq asp.net-core