Почему вызов AsEnumerable () для DataTable предотвращает привязку GridView к нему? - PullRequest
3 голосов
/ 24 февраля 2012

На моей странице .aspx у меня есть элемент управления <asp:GridView runat="server" ID="CustomerGridView">, который я связываю следующим образом:

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

Вот класс DomainManager:

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

Проблемав том, что моя сетка не связана правильно.Почему нет?

1 Ответ

3 голосов
/ 24 февраля 2012

Попробуйте изменить

return dt.AsEnumerable(); 

на

return dt.DefaultView;

Объяснение: По умолчанию GridView привязывается к фактическим свойствам объекта.Например, если источником данных является List<Customer>, то вы можете связать со свойством Name каждого Customer.Но когда источником данных является DataTable клиентов, то каждый клиент представлен DataRow, а DataRow не имеет свойство Name, которое GridView может связатьк.

Для поддержки динамических свойств объект должен реализовывать интерфейс ICustomTypeDescriptor.Этот интерфейс реализован DataRowView, но не DataRow.Изменяя код для возврата dt.DefaultView (то есть DataView), вы предоставляете GridView набор DataRowView объектов, с которыми он может связываться.

Теперь вы можете задаться вопросом, почему

this.CustomerGridView.DataSource = dt;

работает, но

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

не работает.

Причина в том, что DataTable реализует интерфейс IListSource, который сообщает GridView «не используйте меня в качестве источника данных, вместо этого используйте мой DefaultView».Но AsEnumerable() возвращает объект-оболочку, который не реализует IListSource, поэтому GridView не знает, как добраться до DefaultView.

...