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