我在使用它时遇到了一些麻烦。我开始使用一个有效的App: 我有一个“公司”表,与另一个表“组”有多对多的关系。
当get是:
// GET: api/values
[HttpGet]
public IEnumerable<Company> Get()
{
return _dbContext.Companies;
}
一切正常,我得到了所有3条记录。 但是如果我改变实现以包含一些逻辑,主要是检查登录的用户ID并获得与他相关的项目,我什么都没有回到角度。 这是代码:
// GET: api/values
[HttpGet]
public IEnumerable<Company> Get()
{
string userId = User.GetUserId();
var thisUserAndGroups = _dbContext.Users.Where(y => y.Id == userId).Include(x => x.UserGroups).ToList();
List<int> groupIDs = new List<int>();
foreach (UserGroups i in thisUserAndGroups.First().UserGroups)
{
groupIDs.Add(i.GroupId);
}
var GroupsAndCompanies = _dbContext.Groups.Include(x => x.GroupCompanies).Where(a => groupIDs.Contains(a.GroupId)).ToList();
List<int> companyIDs = new List<int>();
foreach (Group g in GroupsAndCompanies)
{
foreach (GroupCompanies gc in g.GroupCompanies)
{
companyIDs.Add(gc.CompanyId);
}
}
IEnumerable<Company> ret = _dbContext.Companies.Where(b => companyIDs.Contains(b.CompanyId)).ToList();
return ret;
}
当我调试它,并将我的断点放在“return ret”行时,它确实有正确的数据。 我的理论说,由于“包含”命令,“公司”被扩展,JSON化不能“吃掉它”,所以它变回空洞。 我对吗?我该如何让它发挥作用?
要清楚我的公司模型是:
public class Company
{
public Company()
{
InfoTabs = new List<InfoTab>();
GroupCompanies = new HashSet<GroupCompanies>();
}
public int CompanyId { get; set; }
[Required]
[StringLength(50)]
public string CompanyName { get; set; }
public virtual ICollection<InfoTab> InfoTabs { get; set; }
public ICollection<GroupCompanies> GroupCompanies { get; set; }
}
组:
public class Group
{
public int GroupId { get; set; }
[Required]
[StringLength(50)]
public string GroupName { get; set; }
[Required]
[StringLength(10)]
public string AccessLevelIT { get; set; }
[Required]
[StringLength(10)]
public string AccessLevelTicketing { get; set; }
public ICollection<GroupCompanies> GroupCompanies { get; set; }
public ICollection<UserGroups> UserGroups { get; set; }
public Group()
{
GroupCompanies = new HashSet<GroupCompanies>();
UserGroups = new HashSet<UserGroups>();
}
}
集团公司(多对多):
public class GroupCompanies
{
public int GroupId { get; set; }
public int CompanyId { get; set; }
public Group Group { get; set; }
public Company Company { get; set; }
}
UserGroups(多对多):
public class UserGroups
{
public int GroupId { get; set; }
public string ApplicationUserId { get; set; }
public ApplicationUser ApplicationUser { get; set; }
public Group Group { get; set; }
}
最后,用户是.net的身份表未触及。刚补充说:
public class ApplicationUser : IdentityUser
{
public ICollection<UserGroups> UserGroups { get; set; }
}
}
修改 正如我怀疑并且@jpgrassi证实的那样,问题是使用“include”创建了一个JSONization无法处理的对象。 目前我添加了代码来绕过问题:
List<Company> retCollection = new List<Company>();
foreach (Company c in ret)
{
Company inner = new Company();
inner.CompanyId = c.CompanyId;
inner.CompanyName = c.CompanyName;
retCollection.Add(inner);
}
return retCollection;
基本上将数据应对于未扩展的公司项目。 然而我知道这很糟糕。请帮我把这段代码写得更好!我确信这不是这样做的方式。
感谢您的帮助!
答案 0 :(得分:0)
所以我最初的意思是:
var userId = "";
var foundCompanies = userGroups
.Where(x => x.ApplicationUserId == userId)
.Join(groupCompanies,
ug => ug.GroupId,
gc => gc.GroupId,
(userGroup, groupCompany) => new { groupCompany.Company })
.ToList();
// so the above statement will get back back a UserGroup and a GroupCompanies where their GroupId match.
因为你有那些连接表,所以这样做更容易。无需通过那些导航属性(我个人讨厌)。
使用join,您必须返回一个匿名对象,因为它正在被转换为SQL。
(userGroup, groupCompany) => new { groupCompany.CompanyId })
此行基本上是Select
行。它定义了您希望如何投影这两个实体之间的关系。我关心的只是公司。但是您可以返回ApplicationUser
和Company
,然后按分组制作不同的结果集。