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

[Solved] Ajax Grid Queries Executed Twice

3 Answers 118 Views
Grid
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Hiram
Top achievements
Rank 1
Hiram asked on 29 Feb 2012, 05:13 PM
 I am using ASP.Net MVC 3 with Telerik.Web.Mvc (ver 2012.1.214.340) and Entity Framwork with late biding enabled. I have a Grid with another Grid inside as detail (hierarchy) with Ajax binding. I follow the sample in http://demos.telerik.com/aspnet-mvc/razor/grid/hierarchyajax. Everything seems to be working fine except that for the inner grids the SQL statement is being called twice. The controller action is being called only once and it returns an IEnumerable LINQ query that has not executed yet. I removed all the paging and sorting from the inner grids and it still called the DB twice.
What am I missing?
Here is my View Code:
@(Html.Telerik().Grid<LPAMSSite.Models.DealInListViewModel>()
    .Name("DealsHierarchyGrid")
    .Columns(columns =>
    {
      columns.Bound(d => d.DealName).Width(200).ClientTemplate(
        Html.ActionLink("<#= DealName #>", "Details", "Deal", new { id = "<#= DealName #>" }, null).ToString());
      columns.Bound(d => d.CMBSDealName).Title("Long Name").Width(250);
      columns.Bound(d => d.LoanCount).Title("Loan Count").Width(150).HtmlAttributes(new { style = "text-align:right" });
      columns.Bound(d => d.PropertyCount).Title("Property Count").Width(150).HtmlAttributes(new { style = "text-align:right" });
    })
        .DetailView(details => details.ClientTemplate(
            Html.Telerik().Grid<LPAMSSite.Models.LoanInListViewModel>()
                .Name("Loans_<#= DealID #>")
                .Columns(columns =>
                {
                  columns.Bound(l => l.LoanNumber).Title("Loan Number").Width(180).ClientTemplate(
                    Html.ActionLink("<#= LoanNumber #>", "Details", "Loan", new { id = "<#= LoanNumber #>" }, null).ToString());
                  columns.Bound(l => l.MaturityDate).Title("Maturity Date").Width(180);
                  columns.Bound(l => l.EndingScheduledBalance).Title("Ending Scheduled Balance").Width(150).Format("{0:c}").HtmlAttributes(new { style = "text-align:right" });
                  columns.Bound(l => l.EventDate).Title("Event Date").Width(120);
                  columns.Bound(l => l.EventReason).Title("Event Reason").Width(200);
                  columns.Bound(l => l.IsActive).Title("Active").Width(100).ClientTemplate("<#= IsActive? 'Yes' : 'No' #>");
                  columns.Bound(l => l.IsInBankruptcy).Title("In Bankruptcy").Width(200).ClientTemplate("<#= IsInBankruptcy? 'Yes' : 'No' #>");
                  columns.Bound(l => l.InterestRate).Title("Interest Rate").Width(200).Format("{0:#0.##%}").HtmlAttributes(new { style = "text-align:right" });
                  columns.Bound(l => l.PropertyCount).Title("Property Count").Width(200).HtmlAttributes(new { style = "text-align:right" });
                })
                .DetailView(propertiesDetailView => propertiesDetailView.ClientTemplate(
                        Html.Telerik().Grid<LPAMSSite.Models.PropertyInListViewModel>()
                          .Name("Properties_<#= LoanID #>")
                        .Columns(columns =>
                        {
                          columns.Bound(p => p.Name).Title("Property Name").Width(233).ClientTemplate(
                            Html.ActionLink("<#= Name #>", "Details", "Property", new { id = "<#= PropertyID #>" }, null).ToString());
                          columns.Bound(p => p.Type).Width(150);
                          columns.Bound(p => p.FullAddress).Title("Address");
                          columns.Bound(p => p.LoanCount).Title("Loan Count").Width(100).HtmlAttributes(new { style = "text-align:right" });
                        })
                        .DataBinding(dataBinding => dataBinding.Ajax()
                                      .Select("_PropertiesHierarchyAjax", "Property", new { id = "<#= LoanID #>" }))
                        .ToHtmlString()
                    ))
                  .DataBinding(dataBinding => dataBinding.Ajax().Select("_LoansHierarchyAjax", "Loan", new { id = "<#= DealID #>" }))
                .ToHtmlString()
    ))
    .DataBinding(dataBinding => dataBinding.Ajax().Select("_DealsHierarchyAjax", "Deal"))
    .Pageable(paging => paging.PageSize(100))
    .Scrollable(scrolling => scrolling.Height(500))
    .Filterable()
    .Sortable()
)
In Controller:
[GridAction]
    public ActionResult _DealsHierarchyAjax()
    {
      return View(new GridModel<DealInListViewModel> { Data = _context.Deals.Select( d =>
        new DealInListViewModel{DealID = d.DealID, DealName =  d.DealName, CMBSDealName = d.CMBSDealName, LoanCount = d.LoanCount, PropertyCount = d.PropertyCount})});
    }[GridAction]
      public ActionResult _LoansHierarchyAjax(int id)
      {
        IEnumerable<Loan> loans;
        #region Filter Loans
        if (id > 0) //getting loans for a given deal
          loans = _context.Loans.Where(l => l.DealID == id);
        else if (id < 0) //getting loans for a given property
          loans = _context.Properties.First(p => p.PropertyID == (id *-1)).Loans;
        else // getting loans based on filters
        {
          loans = _context.Loans;
          //TODO: Put here filter logic
          string dealName = (string)Request["dealName"];
          bool? isActive = (Request["isActive"] == null || Request["isActive"] == Common.YesAndNo ? null : (bool?)(Request["isActive"] == "Yes"));
       
       
          //Active filter
          if (isActive.HasValue)
            loans = loans.Where(l => l.IsActive == isActive);
          //Deal Filter
          if(!string.IsNullOrEmpty(dealName))
            loans = loans.Where(l => l.DealName.Contains(dealName.Trim()));
        }
        #endregion
        #region Create and Return View Model
        return View(new GridModel<LoanInListViewModel>
        {
          Data = loans.Select(l =>
            new LoanInListViewModel
            {
              LoanID = l.LoanID,
              LoanNumber = l.LoanNumber,
              DealName = l.DealName,
              MaturityDate = l.MaturityDate,
              EndingScheduledBalance = l.EndingScheduledBalance,
              EventDate = l.EventDate,
              IsActive = l.IsActive,
              IsInBankruptcy = l.IsInBankruptcy,
              InterestRate = l.InterestRate,
              PropertyCount = l.PropertyCount
            })
        });
        #endregion
      }
[GridAction]
    public ActionResult _PropertiesHierarchyAjax(int id)
    {
      IEnumerable<Property> properties;
      #region Filter Properties
      if (id > 0) //getting Properties for a given Loan
        properties = (IEnumerable<Property>)_context.Loans.First(l => l.LoanID == id).Properties;
      else
      {
        properties = (IEnumerable<Property>)_context.Properties;
        //TODO: Put here filter logic
      } 

3 Answers, 1 is accepted

Sort by
0
Dadv
Top achievements
Rank 1
answered on 01 Mar 2012, 05:50 PM
Hi,

Do you try to bypass the lazy loading to see if the db is call twice? :

 return View(new GridModel<DealInListViewModel> { Data = _context.Deals.Select( d =>
        new DealInListViewModel{DealID = d.DealID, DealName =  d.DealName, CMBSDealName = d.CMBSDealName, LoanCount = d.LoanCount, PropertyCount = d.PropertyCount}).ToList()}); 


and

Data = loans.Select(l =>
            new LoanInListViewModel
            {
              LoanID = l.LoanID,
              LoanNumber = l.LoanNumber,
              DealName = l.DealName,
              MaturityDate = l.MaturityDate,
              EndingScheduledBalance = l.EndingScheduledBalance,
              EventDate = l.EventDate,
              IsActive = l.IsActive,
              IsInBankruptcy = l.IsInBankruptcy,
              InterestRate = l.InterestRate,
              PropertyCount = l.PropertyCount
            }).ToList()
        }); 
0
Hiram
Top achievements
Rank 1
answered on 05 Mar 2012, 04:12 PM
I put the ToList() in the loan list and there was only one call to the DB. The question is why? I have similar code (lazy loading) for the Property (third grid in the hierarchy) and this does not happen.

Thank you.
0
Dadv
Top achievements
Rank 1
answered on 06 Mar 2012, 09:29 AM
hi,

in what i understand of Linq in lazy loading, it create a "grape" for the request, so when you call ToList early , you execute the "grape" early too. I suppose that if you let MVC define when the grape is execute, it encapsulate it in a new 'Select' then the request is execute twice..

I don't know why but i had see that lot of time in my projects. Often it is because of a sub-query inside some of the entities model.

I don't think telerik grid to be in cause here.
Tags
Grid
Asked by
Hiram
Top achievements
Rank 1
Answers by
Dadv
Top achievements
Rank 1
Hiram
Top achievements
Rank 1
Share this question
or