Why does calling AsEnumerable() on a DataTable prevent a GridView from binding to it?

China☆狼群 提交于 2020-01-02 08:54:48

问题


In my .aspx page, I have an <asp:GridView runat="server" ID="CustomerGridView"> control which I bind like this:

public partial class InsertCustomer : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            ViewCustomer();
        }
    }

    private void ViewCustomer()
    {
        var manager = new DomainManager();
        var result = manager.FindAll(new Customer());
        this.CustomerGridView.DataSource = result;
        this.CustomerGridView.DataBind();
    }
}

Here is the DomainManager class:

public class DomainManager
{
    readonly StringBuilder _queryBuilder = new StringBuilder();
    private Type _entityType;
    readonly SQLHelper _sqlHelper = new SQLHelper();

    public IEnumerable FindAll<T>(T entity)
    {
        _entityType = entity.GetType();
        var query = string.Format("select * from {0}", _entityType.Name);
        var dt = _sqlHelper.FillDataTable(query);
        return dt.AsEnumerable();
    }
}

The problem is that my grid is not being bound correctly. Why not?


回答1:


Try changing

return dt.AsEnumerable(); 

to

return dt.DefaultView;

Explanation: By default, a GridView binds to actual properties of an object. For example, if the data source is a List<Customer>, then you can bind to the Name property of each Customer. But when the data source is a DataTable of customers, then each customer is represented by a DataRow, and a DataRow does not have a Name property that the GridView can bind to.

To support dynamic properties, an object must implement the ICustomTypeDescriptor interface. This interface is implemented by DataRowView but not DataRow. By changing the code to return dt.DefaultView (which is a DataView), you provide the GridView with a collection of DataRowView objects that it can bind to.

Now you might be wondering why

this.CustomerGridView.DataSource = dt;

works, but

this.CustomerGridView.DataSource = dt.AsEnumerable();

doesn't.

The reason is that DataTable implements the IListSource interface, which tells the GridView "don't use me as the data source, use my DefaultView instead." But AsEnumerable() returns a wrapper object that doesn't implement IListSource, so the GridView doesn't know how to get to the DefaultView.



来源:https://stackoverflow.com/questions/9432688/why-does-calling-asenumerable-on-a-datatable-prevent-a-gridview-from-binding-t

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!