|
-
Feb 18th, 2008, 10:10 AM
#1
Thread Starter
Frenzied Member
[RESOLVED] [2005] items values changing in list when new item added
Description:
First the explaination of a I have a function that I’ve created. It basically uses reflection to create and return a particular type. Whatever I pass in is what I will get back and the function is complete generic. Heres my two senrios. I also use a class called SafeDataReader, which all it does is simple implement the IDataReader interface and does some behind the scenes things so as to not return a DBNull.Value, if that’s what was returned from the read, but the value you except ie you want a string you get an empty string not a DBNul value. Ok here we go, if I don’t make any sense let me know.
1. I have a class call Abc. It has a property called Name. The constructor is like so… Public Sub New(ByVal dr As SafeDataReader)
2. Now I have a class called AbcXyzManager that inherits from a base class that I’ve created and has a function with the following signature. Protected Function FetchDataObjects(Of T, C As List(Of T))(ByVal objectToCreate As Type, ByVal sqlStatement As String, ByVal params As Core.CSSIDbParameterCollection, Optional ByVal cmdType As CommandType = CommendType.Text) As C
3. Now in a function in the AbcXyzManager class called GetAbcList I setup the sql statement and parameters this function is going to return a List(Of Abc). So the signature of the inherited function would look like so Return FetchDataObjects(Of Abc, List(Of Abc))(GetType(Abc), sql, params).
4. What the code below runs it returns a list of Abc that has 3 items each item has different values.
5. This all works just fine item 1’s Abc.Name = Test1, 2’s Abc.Name = Test2, and 3’s Abc.Name = Test3.
6. Now for the kicker.
7. I do the same exact thing only this time I have a class called Xyz, might have different properties, but the same type of constructor.
8. In the AbcXyzManager I have a function called GetXyzList again I setup everything and then return a List of type Xyz.
9. Again I use the FetchDataObjects the only difference this time is it’s of type Xyz and the list is of type Xyz. So the object that needs to be created is Xyz.
10. When the code runs and reads data creates an instance of Xyz and adds it to the list, everything works fine… Until it reads the next record.
11. When it reads the record, instanciates the Xyz object and calls the constructor everything works as it should. I read the records and setup whatever properties/members need to be in the Xyz object.
12. Now for the real big kicker… Once the newly created object is added to the list. If I look at the list so far only two Xyz objects have been added… you would think that these two items of xyz would have different values for the properties… ie lets say there are two properties Name and Number. Name should be Test1, Number should be 1, because that’s what was read from the first record. Now the second item should have a Name property value of Test2 and a Number property value of 2, because again that’s what was read from the second record. However, if I look at the first item the Name value is Test2 and the Number value is 2. It’s as though it’s over writing the previous item(s).
I’ve stepped through my code and watched each and ever value be set each time a record was read. Each time the values are different and prior to adding the newly created Xyz object to the list the first item has different values. As soon as the new Xyz object is added to the list thouh all previous items in the list take on the values from that Xyz object. Again I use the same code for creating a list of type Abc and it works perfectly fine. Here’s the code of the base class function. The problem occurs when it runs the following code.
vb Code:
Do While dr.Read
retval.Add(Activator.CreateInstance(objectToCreate, New Object() {dr}))
Loop
vb Code:
Protected Function FetchDataObjects(Of T, C As List(Of T))(ByVal objectToCreate As Type, _
ByVal sqlStatement As String, _
ByVal params As DbParameter(), _
Optional ByVal cmdType As CommandType = CommandType.Text) _
As C
Dim retval As List(Of T) = Nothing
Try
m_Cnn = DbProviderFactories.GetFactory(m_Provider).CreateConnection
m_Cnn.ConnectionString = m_CnnStr
m_Cnn.Open()
If m_Cnn.State = ConnectionState.Open Then
m_Cmd = m_Cnn.CreateCommand
m_Cmd.CommandText = sqlStatement
m_Cmd.CommandType = cmdType
If params IsNot Nothing AndAlso params.Count > 0 Then
m_Cmd.Parameters.AddRange(params)
End If
Try
Using dr As New Data.Core.SafeDataReader(m_Cmd.ExecuteReader)
Try
retval = New List(Of T)
Do While dr.Read
retval.Add(Activator.CreateInstance(objectToCreate, New Object() {dr}))
Loop
Catch dbEx As DbException
Throw dbEx
Catch ex As Exception
Throw ex
End Try
End Using
Catch dbEx As DbException
Throw dbEx
Catch ex As Exception
Throw ex
End Try
End If
Catch ex As Exception
Throw ex
Finally
If m_Adapter IsNot Nothing Then
m_Adapter.Dispose()
m_Adapter = Nothing
End If
If m_Cmd IsNot Nothing Then
m_Cmd.Dispose()
m_Cmd = Nothing
End If
If m_Cnn IsNot Nothing Then
'Place closing in try block as the connection
'object may still be disposed.
Try
m_Cnn.Close()
m_Cnn.Dispose()
Finally
m_Cnn = Nothing
End Try
End If
End Try
Return retval
End Function
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|