我正在尝试使用中继器检索所有订单数据。 因此,我面临这个问题,但我以前从未发生过这种错误,因为它可以照常工作。
我的代码:
protected void OrderRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
//Assign status to page variable
status = (Label)e.Item.FindControl("lblStatus");
// Get the current order's data
**DataRowView orderData = (DataRowView)e.Item.DataItem;**
int orderID = orderData.Row.Field<int>("OrderID");
// Filter the DataTable to get items for the current order
DataTable itemsForOrder = ((DataView)TrackingSource.Select(DataSourceSelectArguments.Empty))
.Table
.Select($"OrderID= {orderID}")
.OrderByDescending(x => x.Field<DateTime>("OrderDate"))
.CopyToDataTable();
itemsForOrder.DefaultView.Sort = "OrderDate DESC";
CalculateEstimatedShippingDate(e.Item);
}
else
{
lblFail.Text = "You have no purchased records.";
}
}
来源错误: DataRowView orderData = (DataRowView)e.Item.DataItem;
我认为,由于我使用的是 Visual Studio 2022,因此在编译过程中可能会出现一些错误。它可能会关闭整个窗口并再次打开它。这样就可以正常运行了。这是我的期望。谢谢你。
我应该指出,只有在数据绑定事件期间,数据源项(行)才可用。这当然意味着即使未包含在标记中的列(在本例中为转发器)也可以自由使用和获取。但是,一旦数据绑定完成,数据项(行项)就会超出范围。
因此,请记住,要使上述工作正常进行,您提供给 GridView、ListView 或在本例中为 Repeater 的数据必须是 IEnumerable 数据列表。
这意味着,如果您使用阅读器向控件提供数据,那么 Repeater、ListView 等将起作用,但如果您尝试获取用于绑定的数据行,则它们将不起作用。
所以,拿这个简单的中继器:
<asp:Repeater ID="Repeater1" runat="server"
OnItemDataBound="Repeater1_ItemDataBound">
<ItemTemplate>
<h4 id="myH3" runat="server"><%# Eval("HotelName") %> </h4>
<br />
<hr />
</ItemTemplate>
</asp:Repeater>
以及加载此中继器的代码:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadData();
}
void LoadData()
{
string strSQL =
@"SELECT * FROM tblHotelsA
ORDER BY HotelName";
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL = new SqlCommand(strSQL,conn))
{
conn.Open();
Repeater1.DataSource = cmdSQL.ExecuteReader();
Repeater1.DataBind();
}
}
}
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
// if active column = true, highligt in blue
if ((e.Item.ItemType == ListItemType.Item) ||
(e.Item.ItemType == ListItemType.AlternatingItem))
{
DataRowView MyDataRow = (DataRowView)e.Item.DataItem;
if ((bool)MyDataRow["Active"] == true)
{
HtmlGenericControl H3 = (HtmlGenericControl)e.Item.FindControl("myH3");
H3.Style.Add("background-color", "skyblue");
}
}
}
现在,如果我们不尝试使用上面的代码就可以工作:
DataRowView MyDataRow = (DataRowView)e.Item.DataItem;
因此,为了使 e.Item.DataItem 合法,控件的数据源必须是 IEnumerable,而阅读器则不是。那么,是否可以将 GridView、Repeater 等与非 IEnumerable 的数据源(例如数据转发器)绑定?
是的,你可以!但是,如果这不允许使用 e.Item.DataItem。
因此,为了使上述代码正常工作,我们必须向数据绑定控件提供一个 IEnumberale 列表。
因此,这段代码现在可以工作了:
void LoadData()
{
string strSQL =
@"SELECT * FROM tblHotelsA
ORDER BY HotelName";
DataTable dtHotels = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL = new SqlCommand(strSQL,conn))
{
conn.Open();
dtHotels.Load(cmdSQL.ExecuteReader());
}
}
Repeater1.DataSource = dtHotels;
Repeater1.DataBind();
}
结果现在是这样的:
因此,如果我们不使用 e.Item.DataItem,第一个代码示例将起作用,因为您可以将此类数据感知控件提供给中继器。
但是,当使用 e.Item.DataItem 时,数据源不能是“读取器”,因为它不会生成 IEnumerable 列表 - 允许重复使用每一行的列表,而不是一次逐行读取的读取器使用超出范围。
您没有显示加载中继器数据源的代码,但一个常见的问题是向读取器提供数据控件可以工作,但如果您尝试在行数据绑定中使用 e.Item.DataItem,则它不起作用活动。
所以,对于上面的代码