如何对IQueryable方法进行分组

时间:2018-12-25 07:24:24

标签: linq api model-view-controller onion-architecture

我想对列表进行分组以避免在屏幕上重复记录

我想与SiteToEmp进行内部联接,需要对此进行深入了解 由于我有一个IQueryable方法,该方法从数据库返回列表的另一个表(SiteToEmp)具有关系,当我加入关系时,该关系可以为同一个外键(SiteID)记录多个记录,所以我必须使用按主键进行分组,但失败转换

  protected override IQueryable<SiteViewModel> BuildQuery(byte tab, byte? range, DateTime? start, DateTime? end, string role)
    {
        var source = typeof(Site).Name;
        if (range != null && range != 10 && range != 0)
            RequestUtil.RequestRangeFilter(UnitOfWork, range.Value, Parms.CompanyId, out start, out end);

        var query =
            (from site in UnitOfWork.SiteRepository.GetAll()
             join lookup in UnitOfWork.LookUpRepository.Find(l => l.CodeName == "Sitetype")
                 on site.SiteType equals lookup.CodeId into ldg
             from lookup in ldg.DefaultIfEmpty()

             join lookuptitle in UnitOfWork.LookUpTitlesRepository.Find(l =>
                     l.CodeName == "Sitetype" && l.Culture == Parms.Language)
                 on site.SiteType equals lookuptitle.CodeId into ltdg
             from lookuptitle in ltdg.DefaultIfEmpty()

             join district in UnitOfWork.DistrictRepository.GetAll()
                    on site.DistrictId equals district.Id into g2
             from district in g2.DefaultIfEmpty()

             join city in UnitOfWork.CityRepository.GetAll()
                 on site.CityId equals city.Id into g3
             from city in g3.DefaultIfEmpty()

             join country in UnitOfWork.CountryRepository.GetAll()
                 on site.CountryId equals country.Id into g4
             from country in g4.DefaultIfEmpty()

             join siteToEmp in UnitOfWork.SiteToEmployeesRepository.GetAll()
                 on site.Id equals siteToEmp.SiteId into g
             from siteToEmp in g.DefaultIfEmpty()

             join employee in UnitOfWork.EmployeeViewRepository.GetEmployeesByCompanyId(Parms.CompanyId,
                     Parms.Language)
                 on siteToEmp.EmpId equals employee.EmpId into g1
             from employee in g1.DefaultIfEmpty()

             select new SiteViewModel
             {
                 Id = site.Id,
                 Code = site.Code,
                 Name = site.Name,
                 LocalName = site.Name,
                 TimeZone = site.TimeZone,
                 Latitude = site.Latitude,
                 Longitude = site.Longitude,
                 Address = site.Address1,
                 City = city.Name,
                 District = district.Name,
                 Country = country.Name,
                 SiteTypeName = (lookuptitle == null ? lookup.Name : lookuptitle.Title),
                 SiteToEmployeesList = employee.EmpName,
                 ContactPerson = site.ContactPerson,
                 Email = site.Email,
                 Mobile = site.Telephone
             });//.GroupBy(k => k.Id).ToList(); 

        //var results = query.GroupBy(x => x.Id).ToList();
        return query;
    }

无法将类型System.Linq.IQueryable隐式转换为'System.Linq.IQueryable'  存在显式转换

3 个答案:

答案 0 :(得分:1)

您需要做的是返回每个组的第一项:

var results = query.GroupBy(x => x.Id)
    .Select(g => g.FirstOrDefault())
    .ToList();

我不知道这是否重要,但是当有更多匹配的联接时,这将返回“随机”雇员。您可能需要通过订购组来控制返回哪个员工,例如:

...
.Select(g => g.OrderBy(e => e.SiteToEmployeesList).FirstOrDefault())

顺便说一句,SiteToEmployeesList不包含列表,而仅包含一个名称。最好使用更合适的属性名称。

另一句话:尝试使用导航属性代替所有这些详细的联接。即属性,例如site.District引用一个District对象,或者site.SiteToEmployees包含一个SiteToEmployee对象的列表,等等。

答案 1 :(得分:0)

已通过将方法类型更改为来解决:      公共异步任务>> GetSiteList(字节标签,字节?范围,日期时间?开始,             约会时间? end,string role){//////} 插入:       受保护的重写IQueryable BuildQuery(字节选项卡,字节?范围,日期时间?开始,日期时间?结束,字符串角色)     {////////}

答案 2 :(得分:0)

通过将方法类型更改为来解决:

    public async Task<List<SiteViewModel>> GetSiteList(byte tab, byte? range, DateTime? start, DateTime? end,string role){......} 

代替:

    protected override IQueryable BuildQuery(byte tab, byte? range, DateTime? start, DateTime? end, string role){.....}