【问题标题】:How to pass a list of objects to a gridview datasource without generating a column error如何将对象列表传递给gridview数据源而不产生列错误
【发布时间】:2017-11-23 11:29:41
【问题描述】:

我执行一个基本的 SQL 查询来将数据提供给 Gridview 排序事件。

public DataTable GetDataDataTableGeneric()
{
    string query = "SELECT * FROM Gamer";

    SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["AzureServer"].ConnectionString);
    conn.Open();

    SqlCommand cmd = new SqlCommand(query, conn);

    DataTable dt = new DataTable();
    dt.Load(cmd.ExecuteReader());

    conn.Close();
    return dt;
}

protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
    // string query= e.SortExpression + " " + GetSortDirection(e.SortExpression);
    // e.SortExpression;
    DataTable dt = GetDataDataTableGeneric();
    dt.DefaultView.Sort = e.SortExpression + " " + GetSortDirection(e.SortExpression);

    List<DataRow> list = dt.AsEnumerable().ToList();

    GridView1.DataSourceID = null;

    GridView1.DataSource = list;
    GridView1.DataBind();
}

由于数据源不接受不可枚举的对象,我决定将数据表转换为列表。

但是,我收到此错误:

“System.Data.DataRow”不包含名为“Id”的属性。

有没有办法生成列表并避免错误?

更新 功能:

        protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
    {

        DataTable dt = GetDataDataTableGeneric();
        dt.DefaultView.Sort = e.SortExpression + " " + GetSortDirection(e.SortExpression);
    //    List<Gamer> list = dt.AsEnumerable().ToList();
        List<Gamer> list = (from DataRow row in dt.Rows
         select new Gamer
         {
             //assign properties here
             Id = Convert.ToInt32(row["Id"]),
             UserID = Convert.ToInt32(row["UserID"]),
             Level = Convert.ToInt32(row["Level"]),
             Loyalty = Convert.ToInt32(row["Loyalty"]),
             Experience = Convert.ToInt32(row["Experience"]),
             OverallPoints = Convert.ToInt32(row["OverallPoints"]),
             OverallBets = Convert.ToInt32(row["OverallBets"]),
             Login = row["Login"].ToString()

         }).ToList();

        GridView1.DataSourceID = null;
        GridView1.DataSource = list;
        GridView1.DataBind();

    }

错误

数据源不支持排序。

以下解决方案也失败了。导致同样的排序问题。

    protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
    {

       DataTable dt = GetDataDataTableGeneric();
        dt.DefaultView.Sort = e.SortExpression + " " + GetSortDirection(e.SortExpression);
        List<Gamer> list = (from DataRow row in dt.Rows
         select new Gamer
         {
             //assign properties here
             Id = Convert.ToInt32(row["Id"]),
             UserID = Convert.ToInt32(row["UserID"]),
             Level = Convert.ToInt32(row["Level"]),
             Loyalty = Convert.ToInt32(row["Loyalty"]),
             Experience = Convert.ToInt32(row["Experience"]),
             OverallPoints = Convert.ToInt32(row["OverallPoints"]),
             OverallBets = Convert.ToInt32(row["OverallBets"]),
             Login = row["Login"].ToString()

         }).ToList();
        DataTable dt2 = ConvertToDataTable(list);
        GridView1.DataSourceID = null;
        GridView1.DataSource = dt2;
        GridView1.DataBind();

    }


    private DataTable ConvertToDataTable<T>(IList<T> data)
    {
        PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T));
        DataTable table = new DataTable();
        foreach (PropertyDescriptor prop in properties)
        {
            table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
        }
        foreach (T item in data)
        {
            DataRow row = table.NewRow();
            foreach (PropertyDescriptor prop in properties)
            {
                row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
            }
            table.Rows.Add(row);
        }
        return table;
    }

以下解决方案也未能奏效:

        string cmd = "SELECT * FROM Gamer ORDER BY "+ e.SortExpression + " " + GetSortDirection(e.SortExpression);
        DataSet ds = new DataSet();
        using (SqlConnection connection = new SqlConnection(connectionString))
        {

            SqlDataAdapter sqlAdapter = new SqlDataAdapter(cmd, connection);

            sqlAdapter.Fill(ds);
        }
        GridView1.DataSource = ds;
        GridView1.DataBind();

【问题讨论】:

    标签: c# asp.net sql-server sqldatasource


    【解决方案1】:

    这没有意义,通过将其转换为 List&lt;DataRow&gt; 而您没有将其转换为 List&lt;Gamer&gt; 实际得到了什么,所以这样它就行不通了。

    你可以直接绑定datatable:

    GridView1.DataSource = dt;
    GridView1.DataBind();
    

    或者相反的方法是创建一个类,该类将是一个DTO 对您的表:

    public class Gamer
    {
       public int Id {get;set;}
    }
    

    然后是您的代码,您可以从DataTable 创建一个List&lt;Gamer&gt;,或者从数据访问中直接返回List&lt;Gamer&gt;

    如果您采用第一种方法,您的方法代码将如下所示:

    protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
    {
    
        DataTable dt = GetDataDataTableGeneric();
        dt.DefaultView.Sort = e.SortExpression + " " + GetSortDirection(e.SortExpression);
    
        GridView1.DataSource = dt;
        GridView1.DataBind();
    }
    

    希望对你有帮助。

    【讨论】:

    • 我以前用过那个解决方案。如果你这样做,你得到的错误是“数据源不支持排序”。这是因为 datasource 属性接受一个 IEnumberable 类。这就是我使用铸造的原因。我创建了玩家类,但我有一个铸造问题: List list = dt.AsEnumerable().ToList();我不知道如何进行这种转换,而且我的 linq to sql 知识也不好。
    【解决方案2】:

    你可以使用几个选项,但最简单的一个

        DataTable dt = GetDataDataTableGeneric();
        dt.DefaultView.Sort = e.SortExpression + " " + GetSortDirection(e.SortExpression);
    GridView1.DataSource = dt.DefaultView.ToTable();
        GridView1.DataBind();
    

    或者您可以使用以下函数从 Query 动态创建表,然后将其分配给 GridView

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            NorthwindEntities entity = new NorthwindEntities();
            var db1 = (from ordermst in entity.Orders
                        where ordermst.ShipCountry.Equals("Finland")
                        select new
                        {
                            CustomerID = ordermst.CustomerID,
                            OrderID = ordermst.OrderID
                        }).Take(10).ToList();
            DataTable dt = ConvertToDataTable(db1);
            GvOrder.DataSource = dt;
            GvOrder.DataBind();
     
            DataTable dt1 = new DataTable();
            dt1 = GvOrder.DataSource as DataTable;
            GvOrder1.DataSource = dt1;
            GvOrder1.DataBind();
     
        }
    }
     
    private DataTable ConvertToDataTable<T>(IList<T> data)
    {
        PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T));
        DataTable table = new DataTable();
        foreach (PropertyDescriptor prop in properties)
        {
            table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
        }
        foreach (T item in data)
        {
            DataRow row = table.NewRow();
            foreach (PropertyDescriptor prop in properties)
            {
                row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
            }
            table.Rows.Add(row);
        }
        return table;
    }
    

    【讨论】:

    • 我得到这个错误:数据源不支持排序。使用您的两个代码片段后。您的第二个解决方案已在我上面的答案中更新。
    【解决方案3】:

    奇怪的是,要让它工作,你只需要放置一个空的事件处理程序。

     protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
            {}
    

    【讨论】:

      猜你喜欢
      • 2012-10-28
      • 2013-02-10
      • 2015-08-23
      • 1970-01-01
      • 1970-01-01
      • 2015-06-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多