asp.net - 无法对 DataRows 的 IEnumerable 进行数据绑定(bind)吗? HttpException?

标签 asp.net data-binding ienumerable

我有一个返回 DataTable 的函数,我可以将其数据绑定(bind)到 DropDownlist 或 Repeater 上。但是,如果我对 DataTable 的 DataRows 的 IEnumerable 进行数据绑定(bind),则会收到 HttpException:“DataBinding:'System.Data.DataRow' 不包含名为 'some_column' 的属性”。

repeater.DataSource = ThisReturnsDataTable();  // Works fine
repeater.DataSource = ThisReturnsDataTable.AsEnumerable();  // HttpException

这是为什么?

我并不是在寻找问题的解决方案,例如:

repeater.DataSource = ThisReturnsDataTable().AsEnumerable().Select(
    x => new {some_column = x["some_column"]});

我只是想知道为什么与 DataRows 的 IEnumerable 进行数据绑定(bind)失败。

最佳答案

我找到了一个很好的解释here ,尽管他对这个问题的第一个解决方案 AsDataView() 似乎不起作用/不存在(至少在 3.5 中)。不过,CopyToDataTable() 工作得很好。

.Net DataTables can be very useful when writing data-driven applications. However, they have one limitation: There is no obvious way to databind a grid (or other control) to an arbitrary list of datarows from a table. You can bind to an entire table directly by setting a DataSource to the DataTable itself, and you can bind to a subset of a table by creating a DataView with a filter.

In general, you cannot bind to an IEnumerable (eg, a LINQ query); the databinding infrastructure can only handle an IList (non-generic) or an IListSource. This is true for any kind of datasource. Therefore, to bind to any LINQ query, you need to call .ToList(). (Or .ToArray())

However, when binding to a DataTable, you can’t even use a List. If you try, you’ll get four columns (RowError, RowState, Table, and HasErrors) and no useful information. This happens because the List doesn’t tell the databinding infrastructure about the special properties of the DataRows. To understand the problem, some background is necessary

Databinding is controlled by the ListBindingHelper and TypeDescriptor classes. When you bind to a list, the ListBindingHelper.GetListItemProperties method is called to get the columns in the list. If the list implements the ITypedList interface, its GetItemProperties method is called. Otherwise, it will use TypeDescriptor to get the properties of the first item in the list. (this uses reflection)

The DataView class (which DataTable also binds through, using IListSource) implements ITypedList and returns DataColumnPropertyDescriptors that expose the columns in the table. This is why you can bind to a DataView or DataTable and see columns. However, when you bind to a List, there is no ITypedList that can return the columns as properties. It therefore falls back on reflection and shows the physical properties of the DataRow class.

To solve this issue, you need to wrap the list in a DataView so that you can take advantage of its ITypedList implementation. You can do that using the AsDataView() method. This method is only available on the DataTable and EnumerableRowCollection classes; it cannot be called on an arbitrary LINQ query. You can only get an EnumerableRowCollection by calling special versions of the Cast, OrderBy, Where, and Select methods from a DataTable.

Therefore, you can databind to a simple LINQ query by calling AsDataView() on the query. To bind to a List, or to a more complicated query, you can use an ugly hack:

    List<DataRow> list = ...; 
    grid.DataSource = datatable.AsEnumerable()
                   .Where(list.Contains)
                   .AsDataView();

The AsEnumerable() call is not needed for typed datasets.

You can also call CopyToDataTable(), which will works [sic] on an arbitrary IEnumerable. However, it makes deep copies of the rows, so it isn’t helpful if you want the user to update the data, or if you want the user to see changes made (in code) to the original datarows.

来自:http://blog.slaks.net/2011/01/binding-to-lists-of-datarows.html

关于asp.net - 无法对 DataRows 的 IEnumerable 进行数据绑定(bind)吗? HttpException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10294867/

相关文章:

javascript - VueJS 不在 iframe 内绑定(bind)

c# - 使用 CSVHelper 映射 IEnumerable 属性

c# - 如何在没有任何引用的情况下创建类对象的副本?

java - RoboBinding:firePropertyChange() 上没有此类属性异常

c# - Webforms 数据绑定(bind)与 EF Code-First Linq 查询错误

c# - 多个 IEnumerable 实现悖论

c# - 如何同时遍历两个 IEnumerables?

asp.net - 如何自动化 HTML 可搜索查询数据并将其导出到 Excel

asp.net - Web.HttpContext.Current.User.Identity.Name来自何处?

c# - Kendo Grid 内联编辑日期格式问题