asp.net mvc 3 webgrid bound to List is ex

2019-07-23 22:51发布

问题:

I need to display a data table that can return a variable number of columns in a view, so I am binding an Mvc 3 WebGrid to a List<dynamic>, as described in the answer to this post: Populate MVC Webgrid from DataTable

It works fine, but is incredibly slow! By "incredibly slow" I mean it takes 13 seconds to display a set of 15 records with 11 columns. Is there any way to speed this up? I've tried removing the Pager but that has no effect.

The code that creates the List<dynamic> from an Ado.Net data table looks like this. It runs very quickly, no problem here.

var MyList = new List<dynamic>();
foreach (DataRow row in MyTable.Rows)
{
   var expando = (IDictionary<string, object>)new ExpandoObject();
   foreach (string column in columnNames)
   {
       expando.Add(column, row[column]);
   }
   MyList.Add(expando);
}

The problem occurs in the view. The code below takes about 13 seconds to render a set of 15 records with 11 columns! The trip to the database and the conversion of the data table to a List<dynamic> takes less than a second. The code below takes 13 seconds, just to render. What am I doing wrong? Or am I just barking up the wrong tree using a List<dynamic>?

var grid = new WebGrid(canPage: true, rowsPerPage: Model.PageSize, canSort: false);
 grid.Bind(Model.MyList, rowCount: (int)Model.RowCount, autoSortAndPage: false);
 grid.Pager(WebGridPagerModes.All);
                @grid.GetHtml(tableStyle: "webgrid",
                    rowStyle: "webgrid-row",
                    alternatingRowStyle: "webgrid-alternating-row",
                         htmlAttributes: new { id = "tblSearchResults" },
                         firstText: "<<First",
                         lastText: "Last>>", mode: WebGridPagerModes.All
                )

回答1:

I had the same issue and it was very annoying because we were loading up arbitrary data.

The fix is to define columns and a format function for those columns, this improves the WebGrid performance by a HUGE factor and the performance scales far better (based on number of columns) than without format defined.

e.g.

IEnumerable<KeyValuePair<string, Object>> example = data.First();
foreach (var pair in example)
    cols.Add(grid.Column(
        columnName: pair.Key,
        //Seems that specifying a formatter saves the web grid ridiculous amounts of time
        format: (item => ((IDictionary<String, Object>)item.Value)[pair.Key])
    ));

See my little example project https://github.com/jamesk/MVCWebGridSpeedTest for a speed comparison and full example code.



回答2:

Did you ever get this sorted out? We abandoned WebGrid for a straight up html table with for loops to create CSS styled column headers and row data. @Helper functions were key, and honestly it is easier to control. The performance is very good.

            <table id="moduleGrid" summary="@tableSummary">
                <caption>@tableCaption</caption>
                <thead>
                    <tr>
                        @GridColumnHeaders()
                    </tr>
                </thead>
                <tbody>
                    @GridDataRows()
                </tbody>
            </table>