EF7(beta 7) - 加入多对多表并将数据返回给AngularJS的正确方法是什么?

时间:2015-12-08 10:58:33

标签: angularjs asp.net-web-api entity-framework-core

我在使用它时遇到了一些麻烦。我开始使用一个有效的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;

基本上将数据应对于未扩展的公司项目。 然而我知道这很糟糕。请帮我把这段代码写得更好!我确信这不是这样做的方式。

感谢您的帮助!

1 个答案:

答案 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行。它定义了您希望如何投影这两个实体之间的关系。我关心的只是公司。但是您可以返回ApplicationUserCompany,然后按分组制作不同的结果集。