Grouping with Complex Models

3 posts, 0 answers
  1. Oliver
    Oliver avatar
    8 posts
    Member since:
    Jun 2015

    Posted 05 May Link to this post

    Hello,

    for day I've been trying to get this to work, but with the current state of your documentation its impossible to find anything useful besides maybe Custom Server Binding which probably won't be helpful in my case anyways.

    My problem is basically that grouping works, but it'll completely ignore any properties that are mapped from other models I included via Linq which, for whatever reason, works fine if I don't use grouping at all. I have a property in the ViewModel which displays the Count of the Jobs a Profile has (as seen in the code snipper further down) which will be completely ignored when I have grouping activated.

    I do realize by the way that I could fix my problem by working with a list, but I want to keep using serverside paging and such for performance reasons.

     

    return _context.CrmProfiles.Where(p => ugIds.Contains(p.UserGroupId))
        .Include(p => p.CrmType)
        .Include(p => p.UserGroup)
        .Include(p => p.OrdnungsbegriffType)
        .Include(p => p.Jobs);

     

    This is my Read-Action for filling the grid. I tried different ways to do this, but the result is always the same.

    public virtual ActionResult Read([DataSourceRequest]DataSourceRequest request)
    {
        var samAccountName = Session["SamAccountName"].ToString();
     
        var result = _db.GetProfiles(samAccountName)
            .ToDataSourceResult(request, j => new
            {
                CreatedAt = j.CreatedAt,
                IsGlobalProfile = j.IsGlobalProfile,
                CreatedBy = j.CreatedBy,
                LastUpdatedBy = j.LastUpdatedAt,
                LastUpdatedAt = j.LastUpdatedAt,
                UserGroup = j.UserGroupName,
                Name = j.Name,
                JobCount = j.Jobs.Count
            });
     
        return Json(result);
    }
    var result = _db.GetProfiles(samAccountName)
        .ToDataSourceResult(request, Mapper.Map<CrmProfileGridVM>);

     

     

    And this is my grid:

    (Html.Kendo().Grid<CrmProfileGridVM>()
            .Name("grid-crmprofiles")
            .Columns(c =>
            {
                c.Bound(j => j.Name);
                c.Bound(j => j.IsGlobalProfile).ClientTemplate("<input type='checkbox' disabled #=IsGlobalProfile ? checked='checked' : '' # />").Width(160).Sortable(false);
                c.Bound(j => j.JobCount);
                c.Bound(j => j.UserGroupName);
                c.Bound(j => j.CreatedBy);
                c.Bound(j => j.CreatedAt);
                c.Bound(j => j.LastUpdatedBy);
                c.Bound(j => j.LastUpdatedAt);
            })
            .ToolBar(toolBar => toolBar.Template("<a href='javascript: void(0)' class='button button-create2' title='Neues Profil anlegen' id='bt-profile-create'>button create</a>"))
            .HtmlAttributes(new { style = "height: 680px;" })
            .Editable(editable => editable.Mode(GridEditMode.PopUp))
            .Events(e => {
                e.DataBound("onProfileGridDataBound");})
            .Scrollable()
            .ClientDetailTemplateId("template-grid-crmprofile")
            .Groupable()
            .Sortable()
            .Pageable(pageable => pageable
            .Refresh(true)
            .PageSizes(true)
            .ButtonCount(5))
            .Filterable()
            .DataSource(dataSource => dataSource
                .Ajax()
                .PageSize(20)
                .ServerOperation(true)
                .Model(model => model.Id(p => p.Id))
                .Read(r => r.Action("Read", "CrmProfile"))
                .Events(e => e.Error("onProfileGridError"))
                .Group(g => g.Add(p => p.UserGroupName))
            )
    )

     

    Could somebody please explain to me what the problem is? As far as I can tell AggregateFunctionsGroup is the reason why, but again .. no clue how to fix this.

     

  2. Oliver
    Oliver avatar
    8 posts
    Member since:
    Jun 2015

    Posted 05 May Link to this post

    So I took another look at the example for Custom Server Binding and Grouping actually works .. that is if I don't care about paging, filtering and sorting which obviously isn't the case. Why did you people never bothered to take ViewModels into consideration?

    I can't do anything, because your implementation doesn't have an option to convert the data into ViewModels. The only option I have is to convert the data into the ViewModel before the selector is invoked, but that obviously won't work, because the paging can't work on an ViewModel.

    So what I have to do is 'somehow' invoke the selector before I do the grouping so that the paging is already done by the time the grouping starts and then invoke it again.

    public static IEnumerable ApplyGrouping(this IQueryable<CrmProfile> data, IList<GroupDescriptor>
        groupDescriptors)
    {
        if (groupDescriptors != null && groupDescriptors.Any())
        {
            Func<IEnumerable<CrmProfileGridVM>, IEnumerable<AggregateFunctionsGroup>> selector = null;
            foreach (var group in groupDescriptors.Reverse())
            {
                if (selector == null)
                {
                    if (group.Member == "UserGroupName")
                    {
                        selector = profiles => BuildInnerGroup(profiles, p => p.UserGroupName);
                    }
                }
            }
     
            var pData = Mapper.Map<IEnumerable<CrmProfileGridVM>>(data);
     
            return selector.Invoke(pData).ToList();
        }
        return data;
    }

     

     

  3. Boyan Dimitrov
    Admin
    Boyan Dimitrov avatar
    1961 posts

    Posted 09 May Link to this post

    Hello Oliver,

    Indeed this is the only solution here - invoke the selector before the grouping to have the paging done and invoke it again. 

    Regards,
    Boyan Dimitrov
    Telerik by Progress
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Back to Top