Asp.net 将新对象添加到ArrayList中,当前会重写最后一个对象

Asp.net 将新对象添加到ArrayList中,当前会重写最后一个对象,asp.net,vb.net,Asp.net,Vb.net,我正在将产品添加到ArrayList中,以使用中继器显示 Protected Sub Add_Click(sender As Object, e As EventArgs) Handles Add.Click Dim ProductID As Integer = ddProduct.SelectedValue Dim Qty As Integer = QtyBox.Text Dim TempProduct As OrderEntry = fillProduct(Pr

我正在将产品添加到ArrayList中,以使用中继器显示

   Protected Sub Add_Click(sender As Object, e As EventArgs) Handles Add.Click
    Dim ProductID As Integer = ddProduct.SelectedValue
    Dim Qty As Integer = QtyBox.Text
    Dim TempProduct As OrderEntry = fillProduct(ProductID, Qty)
    OrderList.Add(TempProduct)
    Orders.DataSource = OrderList
    Orders.DataBind()
   End Sub
但是,当我添加一个新对象时,它会用一个新对象替换旧对象,并且我假设它引用了旧对象,而不是创建一个新对象。我在哪里创建一个新的

Imports System.Data
Imports System.Data.SqlClient


Partial Class placeOrder
Inherits System.Web.UI.Page
Dim OrderList As New ArrayList
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load


    If Not Page.IsPostBack() Then
        dataFill()
    End If

End Sub

Private Sub dataFill()
    fillProduct()

End Sub
Private Sub fillProduct()
    Dim conn As New SqlConnection(ConfigurationManager.ConnectionStrings("class_readonly").ConnectionString)
    'Here bad connection string is a problem
    conn.Open()

    'Dim cmd As SqlCommand = conn.CreateCommand()
    Dim sqlCmd As New SqlCommand()
    With sqlCmd
        .Connection = conn
        .CommandText = "SELECT distinct ProductID, Name FROM dbo.Product;"
    End With

    Dim objDataAdapter As New SqlDataAdapter()
    Dim objDataSet As New DataSet()
    objDataAdapter.SelectCommand = sqlCmd

    objDataAdapter.Fill(objDataSet)
    ddProduct.DataSource = objDataSet.Tables(0)
    ddProduct.DataBind()
End Sub

Protected Sub Add_Click(sender As Object, e As EventArgs) Handles Add.Click
    Dim ProductID As Integer = ddProduct.SelectedValue
    Dim Qty As Integer = QtyBox.Text
    Dim TempProduct As OrderEntry = fillProduct(ProductID, Qty)
    OrderList.Add(TempProduct)
    Orders.DataSource = OrderList
    Orders.DataBind()
    dataFill()


End Sub

Private Function fillProduct(ByVal ProductID As Integer, ByVal Qty As Integer) As OrderEntry
    Dim conn As New SqlConnection(ConfigurationManager.ConnectionStrings("class_readonly").ConnectionString)
    'Here bad connection string is a problem
    conn.Open()

    'Dim cmd As SqlCommand = conn.CreateCommand()
    Dim sqlCmd As New SqlCommand()
    With sqlCmd
        .Connection = conn
        .CommandText = "SELECT * FROM dbo.Product WHERE ProductID=@ProductID ;"
        .Parameters.Add(New SqlParameter("@ProductID", SqlDbType.Int, 4)).Value = ProductID
    End With
    Dim objDataAdapter As New SqlDataAdapter()
    Dim objDataSet As New DataSet()
    objDataAdapter.SelectCommand = sqlCmd

    objDataAdapter.Fill(objDataSet)

    Dim dtRow As DataRow = objDataSet.Tables(0).Rows(0)
    Dim Total_Cost As Decimal = Decimal.Multiply(Qty, dtRow("Wholesale_Price"))
    Dim Total_Price As Decimal = Decimal.Multiply(Qty, dtRow("Retail_Price"))
    Dim Profit As Decimal = Total_Price - Total_Cost
    Dim productInfo As New OrderEntry(dtRow("ProductID"), Qty, Total_Cost, Total_Price, Profit, dtRow("Name"))

    sqlCmd.Dispose()
    conn.Dispose()
    Return productInfo
End Function

End Class

好的,这是一个ASP.NET网页。单击按钮后,它会将页面发回服务器。OrderList不会在调用之间持久化,每次单击都会重新初始化。尝试在按钮单击过程中将OrderList添加到会话变量,如下所示:

OrderList.Add(TempProduct)
Session("OrderList") = OrderList
在页面加载事件中,插入:

OrderList = Session("OrderList")

此外,数据填充过程也是多余的。删除该过程并用fillProduct替换对dataFill的调用。这不是一个错误,但它不整洁。

正如@OneFineDay所指出的,如果数组中的每个元素都是相同的类型,那么就使用“List of”类型的对象,而不是“ArrayList”

这就是你们班的样子。您正在单击“添加”将列表保存到会话变量中。在Page_Load中,您将检索此会话变量,将其强制转换为(OrderEntry的)列表,并将其分配回页面级别的列表变量。我还删除了不必要的数据填充过程。确保您理解这些概念,而不仅仅是复制和粘贴

Imports System.Data
Imports System.Data.SqlClient

Partial Class placeOrder
Inherits System.Web.UI.Page

Private m_myOrderList As List(Of OrderEntry)

Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
    If Not Page.IsPostBack() Then fillProduct()
    m_myOrderList = CType(Session("MyOrderList"), List(Of OrderEntry))
End Sub

Private Sub fillProduct()
    Dim conn As New SqlConnection(ConfigurationManager.ConnectionStrings("class_readonly").ConnectionString)
    'Here bad connection string is a problem
    conn.Open()

    'Dim cmd As SqlCommand = conn.CreateCommand()
    Dim sqlCmd As New SqlCommand()
    With sqlCmd
        .Connection = conn
        .CommandText = "SELECT distinct ProductID, Name FROM dbo.Product;"
    End With

    Dim objDataAdapter As New SqlDataAdapter()
    Dim objDataSet As New DataSet()
    objDataAdapter.SelectCommand = sqlCmd

    objDataAdapter.Fill(objDataSet)
    ddProduct.DataSource = objDataSet.Tables(0)
    ddProduct.DataBind()
End Sub

Protected Sub Add_Click(sender As Object, e As EventArgs) Handles Add.Click
    If IsNothing(m_myOrderList) = True Then m_myOrderList = New List(Of OrderEntry)
    Dim ProductID As Integer = ddProduct.SelectedValue
    Dim Qty As Integer = QtyBox.Text
    Dim TempProduct As OrderEntry = fillProduct(ProductID, Qty)
    m_myOrderList.Add(TempProduct)
    Session("MyOrderList") = m_myOrderList
    Orders.DataSource = m_myOrderList
    Orders.DataBind()
  End Sub

Private Function fillProduct(ByVal ProductID As Integer, ByVal Qty As Integer) As OrderEntry
    Dim conn As New SqlConnection(ConfigurationManager.ConnectionStrings("class_readonly").ConnectionString)
    'Here bad connection string is a problem
    conn.Open()

    'Dim cmd As SqlCommand = conn.CreateCommand()
    Dim sqlCmd As New SqlCommand()
    With sqlCmd
        .Connection = conn
        .CommandText = "SELECT * FROM dbo.Product WHERE ProductID=@ProductID ;"
        .Parameters.Add(New SqlParameter("@ProductID", SqlDbType.Int, 4)).Value = ProductID
    End With
    Dim objDataAdapter As New SqlDataAdapter()
    Dim objDataSet As New DataSet()
    objDataAdapter.SelectCommand = sqlCmd

    objDataAdapter.Fill(objDataSet)

    Dim dtRow As DataRow = objDataSet.Tables(0).Rows(0)
    Dim Total_Cost As Decimal = Decimal.Multiply(Qty, dtRow("Wholesale_Price"))
    Dim Total_Price As Decimal = Decimal.Multiply(Qty, dtRow("Retail_Price"))
    Dim Profit As Decimal = Total_Price - Total_Cost
    Dim productInfo As New OrderEntry(dtRow("ProductID"), Qty, Total_Cost, Total_Price, Profit, dtRow("Name"))

    sqlCmd.Dispose()
    conn.Dispose()
    Return productInfo
End Function

End Class

你能给我们看一下fillProduct的功能吗?是的!我更新了最上面的帖子。
列表(OrderEntry)
现在比
ArrayList
更受欢迎。我开始发现这是一个“System.NullReferenceException”类型的异常,发生在App_Web_yc1evu5x.dll中,但没有在OrderList上的用户代码错误中处理。添加(TempProduct)这需要一些修改。我发布了另一个答案。这也是一个优秀的视频,概述了.NET从ArrayList等非类型集合到List(of T)等通用集合的演变。前者实际上是遗留代码。非常感谢你!成功了。你能解释一下,如果IsNothing(m_myOrderList)=True,那么m_myOrderList=New List(Of OrderEntry)List(Of T)是一个引用类型,这意味着它是一个指向值的指针,而不是存储值本身。没有New关键字的引用类型的变量声明将默认为Nothing。Nothing是空引用,这意味着它不指向任何值。请注意,我已经在页面顶部的变量声明中删除了New关键字。在实际需要之前,不需要保留内存。如果省略按钮单击过程的第一行,当您添加第一项时,您将在m_myOrderList.Add(TempProduct)上看到一个空引用,因为m_myOrderList引用指向“Nothing”。Nothing和对空列表的引用之间有很大区别。因此,该行检查m_myOrderList是否没有指向任何内容,如果是,则使用m_myOrderList=新列表(OrderEntry的)使其指向某个内容(空列表)。在将第一个TempProduct对象添加到列表之前,它将不指向任何内容。我还要补充一点,如果您需要使用非类型化列表,因为列表中的元素具有不同的类型,那么您可以始终使用list(of Object)。