如何在不生成列错误的情况下将对象列表传递给 gridview 数据源
How to pass a list of objects to a gridview datasource without generating a column error
我执行基本的 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' does not contain a property with the name '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();
}
错误
The data source does not support sorting.
以下解决方案也失败了。导致同样的排序问题。
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();
这没有意义,实际上通过将它转换为 List<DataRow>
而你没有将它转换为 List<Gamer>
,所以这种方式是行不通的。
你可以直接绑定数据table:
GridView1.DataSource = dt;
GridView1.DataBind();
或者相反的方法是创建一个 class 这将是一个 DTO
反对你的 table :
public class Gamer
{
public int Id {get;set;}
}
然后是您的代码,您可以从 DataTable
或数据访问中创建一个 List<Gamer>
,您可以直接 return List<Gamer>
.
如果您采用第一种方法,您的方法代码将如下所示:
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
DataTable dt = GetDataDataTableGeneric();
dt.DefaultView.Sort = e.SortExpression + " " + GetSortDirection(e.SortExpression);
GridView1.DataSource = dt;
GridView1.DataBind();
}
希望对您有所帮助。
您可以使用多个选项,但最简单的一个
DataTable dt = GetDataDataTableGeneric();
dt.DefaultView.Sort = e.SortExpression + " " + GetSortDirection(e.SortExpression);
GridView1.DataSource = dt.DefaultView.ToTable();
GridView1.DataBind();
或者您可以使用以下函数从 Query 动态创建 table,然后将其分配给 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;
}
奇怪的是,要使它正常工作,您只需要放置一个空的事件处理程序即可。
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{}
我执行基本的 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' does not contain a property with the name '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();
}
错误
The data source does not support sorting.
以下解决方案也失败了。导致同样的排序问题。
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();
这没有意义,实际上通过将它转换为 List<DataRow>
而你没有将它转换为 List<Gamer>
,所以这种方式是行不通的。
你可以直接绑定数据table:
GridView1.DataSource = dt;
GridView1.DataBind();
或者相反的方法是创建一个 class 这将是一个 DTO
反对你的 table :
public class Gamer
{
public int Id {get;set;}
}
然后是您的代码,您可以从 DataTable
或数据访问中创建一个 List<Gamer>
,您可以直接 return List<Gamer>
.
如果您采用第一种方法,您的方法代码将如下所示:
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
DataTable dt = GetDataDataTableGeneric();
dt.DefaultView.Sort = e.SortExpression + " " + GetSortDirection(e.SortExpression);
GridView1.DataSource = dt;
GridView1.DataBind();
}
希望对您有所帮助。
您可以使用多个选项,但最简单的一个
DataTable dt = GetDataDataTableGeneric();
dt.DefaultView.Sort = e.SortExpression + " " + GetSortDirection(e.SortExpression);
GridView1.DataSource = dt.DefaultView.ToTable();
GridView1.DataBind();
或者您可以使用以下函数从 Query 动态创建 table,然后将其分配给 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;
}
奇怪的是,要使它正常工作,您只需要放置一个空的事件处理程序即可。
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{}