1

I am adding products to an ArrayList to display with a repeater

   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

However, when I add a new object, it replaces the old one with a new, and I assume its because it references the old object, instead of creating a new one. Where do I create a new one?

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
3
  • can you show us the fillProduct function? Commented May 1, 2014 at 16:29
  • Yeap! I updated the top post. Commented May 1, 2014 at 16:50
  • A List(Of OrderEntry) is preferred nowadays to the ArrayList. Commented May 1, 2014 at 17:06

2 Answers 2

1

As @OneFineDay points out, if each element of your array is going to be of the same type then use an object of type "List Of" instead of "ArrayList".

This is how your class should look. You are saving your list to a session variable in Add_Click. In Page_Load, you are retrieving this session variable, casting it to a List(Of OrderEntry) and assigning it back to your page level list variable. Also I have removed the unnecessary dataFill procedure. Make sure that you understand the concepts rather than just copying and pasting.

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
Sign up to request clarification or add additional context in comments.

5 Comments

Also this is an excellent video which outlines the evolution of .NET from untyped collections such as the ArrayList to generic collections such List(Of T). The former is effectively legacy code. youtu.be/5E6sMxzNMqQ
Thank you very much! It worked. Can you explain If IsNothing(m_myOrderList) = True Then m_myOrderList = New List(Of OrderEntry)
List (Of T) is a reference type which means that it is a pointer to values rather that storing values itself. A variable declaration of a reference type without the New keyword will default to Nothing. Nothing is a null reference which means it points to no value. Notice that I have dropped the New keyword in the variable declaration at the top of the page.
There is no need to reserve memory until it is actually required. If you omit the first line of the button click procedure, you will see a null reference on m_myOrderList.Add(TempProduct) when you go to add the first item because the m_myOrderList reference is pointing to "Nothing".
There is a big difference between Nothing and a reference to an empty list. So that line checks to see whether the m_myOrderList is pointing to Nothing and if it is, we make it point to something (an empty list) with m_myOrderList = New List(Of OrderEntry). It will be pointing to nothing prior to adding the first TempProduct object to the list. I'll also add that if you need to use an untyped list because the elements of the list are of different types then you can always use List (Of Object).
0

OK so it's an ASP.NET webpage. After you click on the button, it's posting the page back to the server. OrderList does not persist between calls and is reinitialised with each click. Try adding OrderList to a session variable as follows in your button click procedure :

OrderList.Add(TempProduct)
Session("OrderList") = OrderList

and in your page load event, insert:

OrderList = Session("OrderList")

Also your dataFill procedure is superfluous. Delete that procedure and replace calls to dataFill with fillProduct. It's not an error but it's untidy.

2 Comments

I started getting this An exception of type 'System.NullReferenceException' occurred in App_Web_yc1evu5x.dll but was not handled in user code error on OrderList.Add(TempProduct)
This needs some modification. I am posting another answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.