This is a migrated thread and some comments may be shown as answers.

Grouping with Complex Models

2 Answers 51 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Oliver
Top achievements
Rank 1
Oliver asked on 05 May 2017, 06:13 AM

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 Answers, 1 is accepted

Sort by
0
Oliver
Top achievements
Rank 1
answered on 05 May 2017, 07:51 AM

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;
}

 

 

0
Boyan Dimitrov
Telerik team
answered on 09 May 2017, 12:19 PM

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.
Tags
Grid
Asked by
Oliver
Top achievements
Rank 1
Answers by
Oliver
Top achievements
Rank 1
Boyan Dimitrov
Telerik team
Share this question
or