Search code examples
asp.net-mvcentity-frameworkkendo-uitelerikkendo-asp.net-mvc

Kendo MVC Grid DataSourceResult to list of objects


I have a Kendo grid in MVC which is filled with data from T1ViewModel (joined from T1 in DB1 and T2 in DB2, where T1 and T2 are tables, DB1 and DB2 are databases).

T1 has a ShopID column, and the ShopName column exists in T2 of DB2.

I am using Entity Framework with two contexts. I'm loading data from T1 into memory and then joining with T2, as I am only showing 10 records per page, and T1 and T2 have millions of records. This join happens on every page change which is hitting the performance.

Then I use DataSourceRequest to filter the records from T1.

public ActionResult T1_Read([DataSourceRequest] DataSourceRequest request)
{
    using(var context = new DB1Context())
    {
        // Get requested records from T1 into T1ViewModel which has shop name property
        DataSourceResult result = context.T1.select(r => new T1ViewModel{ShopId = r.ShopID.....}).ToDataSourceResult(request)
    }
    
    IEnumerable<T1ViewModel> T1RecordsFiltered = result.data;
    var ShopIds = T1RecordsFiltered.Select(T => T.ShopID);
    
    using(var context = new DB2Context())
    {
        // Get the T2 records that has matching ShopId in the list(ShopIds)
        var T2RecordsFiltered = context.T2.Where(T => ShopIds.Contains(T.ShopID)).ToList();
    }
    
    var t1ViewModel = 
        from t1rf in T1RecordsFiltered
        join t2rf in T2RecordsFiltered on t1rf.ShopID equals t2rf.ShopID into t2rfGroup
        from t2rfg in t2rfGroup.DefaultIfEmpty()
        select new { t1rf, t2rfg };
                  
    var t1ViewModelDetails = t1ViewModel.Select(t =>
    {
        t.t1rf.ShopName = t.t2rfg.ShopName;
        return t.t1rf;
    });
    
    result.data = t1ViewModelDetails;
    
    return Json(result, JsonRequestBehavior.AllowGet);  
}

Now the problem is that my grid is groupable as well. But when I use that feature, result.data has list of AggregateFunctionsGroup. So I am not able to convert result.data into list of T1ViewModel.

Is this right way to do this? Is there a better approach?


Solution

  • Found the solution. Rather than depending on the data of dataSourceResult I used ToDataSourceResult overloaded method to create the list of t1ViewModels and modified the tViewModels to update the shopName as shown below.

    public ActionResult T1_Read([DataSourceRequest] DataSourceRequest request)
    {
        List<T1ViewModel> t1ViewModels = new List<T1ViewModel>();
        DataSourceResult result;
        
        using (var context = new DB1Context())
        {
            // Get requested records from T1 into T1ViewModel which has shop name property
            result = context.T1.ToDataSourceResult(request, t =>
            {
                T1ViewModel tvm = T1ViewModel.FromModel(t);
                t1ViewModels.Add(tvm);
                return tvm;
            });
        }
        
        var ShopIds = t1ViewModels.Select(T => T.ShopID);
    
        using (var context = new DB2Context())
        {
            // Get the T2 records that has matching ShopId in the list(ShopIds)
            var T2RecordsFiltered = context.T2
                .Where(T => ShopIds.Contains(T.ShopID))
                .ToList();
        }
        
        var t1ViewModelDetails = 
            from t1vm in t1ViewModels
            join t2rf in T2RecordsFiltered on t1vm.ShopID equals t2rf.ShopID into t2rfGroup
            from t2rfg in t2rfGroup.DefaultIfEmpty()
            select new { t1vm, t2rfg };
    
        t1ViewModelDetails.Select(t =>
        {
            t.t1vm.ShopName = t.t2rfg.ShopName;
            return t.t1vm;
        });
    
        return Json(result, JsonRequestBehavior.AllowGet);
    }