Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ASP .NET Web Developer s Guide - Mesbah Ahmed, Chris Garrett

.pdf
Скачиваний:
37
Добавлен:
24.05.2014
Размер:
7.32 Mб
Скачать

600 Chapter 13 • Creating a Message Board with ADO and XML

we mean it contains a private ArrayList thereby holding its list of Threads, and exposes certain custom functionalities not necessarily pre-built into the ArrayList class. Let’s take a look at a UML diagram for the ThreadList class in Figure 13.26.

Figure 13.26 The ThreadList Class

ThreadList

+Count : Integer +Item

+InitializeThreads()

As you can see from this diagram, there isn’t much to the ThreadList. It contains a count of the number of Threads in the list, contains an Item property to allow you to access the Threads in the list, and gives you the ability to manually force the reinitialization of the list through the InitializeThreads method. Again, let’s start at the basics and build up from there in Figure 13.27 (which can also be found on your CD under the name ThreadList.vb).

Figure 13.27 The Basics (ThreadList.vb)

Public Class ThreadList

Private list As ArrayList

Private mBoardID As Long

Public Sub New(ByVal BoardID As Long)

mBoardID = BoardID

Me.InitializeThreads()

End Sub

Public ReadOnly Property Count() As Integer

Get

Return list.Count

End Get

End Property

End Class

The ThreadList class contains only two private fields: list and mBoardID.The list variable is used to hold all your Threads, and mBoardID is used to look up

www.syngress.com

Creating a Message Board with ADO and XML • Chapter 13

601

the Threads in a given Board.The constructor accepts a BoardID, and calls the InitializeThreads method, as shown in Figure 13.28.

Figure 13.28 The InitializeThreads Method (ThreadList.vb)

Public Sub InitializeThreads()

Dim myData As DataSet

Dim sql As String

sql = "SELECT [Threads].*, [Users].* FROM [Threads] " & _ "INNER JOIN [Users] " & _

"ON [Users].[UserID] = [Threads].[CreatorID] " & _ "WHERE " & _

"[BoardID] = " & mBoardID.ToString() & _ " ORDER BY [Threads].[ThreadID] DESC"

myData = DataControl.GetDataSet(sql) list = New ArrayList()

Dim myRow As DataRow

For Each myRow In myData.Tables(0).Rows list.Add(myRow)

Next

End Sub

The InitializeThreads method is rather straightforward, but there is one major concept that needs to be mentioned. First, a SQL statement is built to select the Threads located in the appropriate Board (this is where the mBoardID variable comes into play).The SQL statement also joins on the Users table, to allow for the Thread object to know about the User who created the Thread. Next, the list is initialized, and each DataRow in the resultant DataSet is added to the list.This is where the important concept is.The private list currently contains a set of DataRow objects. Obviously, you do not want to expose a bunch of DataRow objects as your list of Threads, so this is where the Item property comes into effect. See Figure 13.29 regarding the Item property.

www.syngress.com

602 Chapter 13 • Creating a Message Board with ADO and XML

Figure 13.29 The Item Property (ThreadList.vb)

Public Function Item(ByVal index As Integer) As Thread

1Dim myObject As Object = list.Item(index)

2If myObject.GetType() Is GetType(Thread) Then

3'it is already a thread, so nothing further is needed

4Else

5Dim myThread As Thread

6myThread = New Thread(CType(list.Item(index), DataRow))

7'replace the item in the list with

8'an actual thread object

9list.Item(index) = myThread

10End If

11

12 Return CType(list.Item(index), Thread)

End Function

The Item property is a little more complex than the average property. Let’s review it, line by line. Line 1 creates a variable called myObject of type Object and sets it equal to the object that is at the specified index of the ArrayList. Line 2 compares the type of the object to the type of the Thread class. If they are the same, it does nothing; if not, it enters the Else part of the If statement (lines 5 – 9). Next, a Thread variable called myThread is declared and set to a new Thread on line 6, passing in the object that is in the specified index in the ArrayList.That object is cast to a DataRow using CType. Line 9 sets the object at the specified index in the ArrayList to the myThread variable. Finally, on line 12 it returns the Thread that is in the specified index of the ArrayList (and again, is cast to be a Thread object).

You may be wondering to yourself exactly what all of this accomplishes.Well, if you remember from the InitializeThreads method, the ArrayList is filled with DataRow objects.We do not want to directly expose anyone using our objects to DataRow objects, so we need to instead give them Thread objects. So, behind the scenes, every time a new index is requested from the ArrayList, we quietly “switch” the variable in that index from a DataRow to the appropriate Thread object.You may also ask why this class doesn’t just put the Threads into the ArrayList from the start instead of doing it this way.The answer is simple: there is no need for the overhead of having multiple Thread objects (each with other

www.syngress.com

Creating a Message Board with ADO and XML • Chapter 13

603

objects inside them) in the list when you can save memory and time instantiating objects by just keeping the data for each Thread object until it is actually requested.When developing large-scale applications with many parent-child hierarchical relationships, a technique like this will save you and your application a lot of time.

Designing the Thread class

The Thread class is the “middle child” in our hierarchy of objects. Luckily for us, a lot of its functionality and concepts are borrowed directly from the Board class, so this should be pretty quick. Let’s take a look at another UML diagram in Figure 13.30.

Figure 13.30 The Thread Class

Thread

+ID : Long +Subject : String +Creator : User +ChildPost +ChildPosts

+CreatePost()

Like every class we’ve examined so far, the Thread class shares the same private fields as the Thread table in the database. Like the Board class, the Thread class contains two properties to access its children: ChildPost and ChildPosts. ChildPost retrieves an individual Post object from its list, and ChildPosts returns the entire PostList. PostList will be discussed a bit later.Thread also contains the method to create child Posts. Let’s start with the basics in Figure 13.31.

Figure 13.31 The Basics (Thread.vb)

Public Class Thread

Private mThreadID As Long

Private mSubject As String

Private mCreator As User

Private myPosts As PostList

Public Sub New(ByVal myRow As DataRow) inflate(myRow)

End Sub

Continued

www.syngress.com

604 Chapter 13 • Creating a Message Board with ADO and XML

Figure 13.31 Continued

Private Sub inflate(ByVal myRow As DataRow) mSubject = CStr(myRow("ThreadSubject")) mThreadID = CLng(myRow("ThreadID")) mCreator = New User(myRow)

myPosts = New PostList(mThreadID) End Sub

Public ReadOnly Property ChildPost(ByVal postId As Long) _

As Post

Get

'lookup the correct Post Dim i As Integer

For i = 0 To Me.ChildPosts.Count - 1

Dim myPost As Post = Me.ChildPosts.Item(i)

If myPost.ID = postId Then

Return myPost

End If

Next i

'if we've gotten to this point, there is no Post 'with that ID in this board. throw an exception Throw New ArgumentException("Post does not exist")

End Get

End Property

Public ReadOnly Property ChildPosts() As PostList

Get

Return myPosts

End Get

End Property

Public ReadOnly Property ID() As Long

Get

Continued

www.syngress.com

Creating a Message Board with ADO and XML • Chapter 13

605

Figure 13.31 Continued

Return mThreadID

End Get

End Property

Public Property Subject() As String

Get

Return mSubject

End Get

Set(ByVal Value As String)

mSubject = Value

End Set

End Property

Public ReadOnly Property Creator() As User

Get

Return mCreator

End Get

End Property

End Class

First, you’ll notice the private fields that are the same as the fields in the database.You’ll also notice that a Thread has a Creator field and property that are User objects representing the user that created this Thread. Like the Board class, this class has a constructor that accepts a DataRow as a parameter and then calls inflate to fill up the private fields using that DataRow. Also like Board, you have two child object properties, ChildPost and ChildPosts. ChildPost is used to return a single Post, and ChildPosts is used to return the entire PostList. Let’s take a look at the next method in the Thread class, CreatePost, in Figure 13.32.

Figure 13.32 The CreatePost Method (Thread.vb)

Public Sub CreatePost(ByVal subject As String, _

ByVal body As String, _

ByVal creator As User)

Continued

www.syngress.com

606 Chapter 13 • Creating a Message Board with ADO and XML

Figure 13.32 Continued

Dim sql As String

sql = "INSERT INTO [Posts] ([PostSubject], " & _ "[PostBody], " & _

"[CreatorID], [ThreadID]) VALUES ('" & subject & _ "','" & body & "'," & creator.ID.ToString() & "," & _ mThreadID.ToString() & ")"

DataControl.ExecuteNonQuery(sql)

'reinitialize the thread list myPosts.InitializePosts()

End Sub

Taking a look at the CreatePost method, you’ll notice that it does almost exactly what CreateThread did in the Board class. It builds a SQL statement to create a new Post, then executes that statement and reinitializes the private

PostList object.

Designing the PostList Class

Being that we’re almost finished creating our classes, it’s time to look at the PostList class.You may be thinking to yourself “I wonder if the PostList class is similar to the ThreadList class”. Such thinking should be rewarded. PostList and ThreadList are nearly identical, except for in regards to what type of object they collect. Again, let’s take a look at the UML diagram for the class first in Figure 13.33, then in Figure 13.34 we’ll review the basics of this class (something which can also be found on your CD as PostList.vb).

Figure 13.33 The PostList Class

PostList

+Count : Integer +Item

+InitializePosts()

Figure 13.34 The Basics (PostList.vb)

Public Class PostList

Private list As ArrayList

Private mThreadID As Long

Continued

www.syngress.com

Creating a Message Board with ADO and XML • Chapter 13

607

Figure 13.34 Continued

Public Sub New(ByVal ThreadID As Long)

mThreadID = ThreadID

Me.InitializePosts()

End Sub

Public Sub InitializePosts()

Dim myData As DataSet

Dim sql As String

sql = "SELECT [Users].*, [Posts].* FROM " & _ "[Posts] INNER JOIN [Users] " & _

"ON [Users].[UserID] = [Posts].[CreatorID] " & _ "WHERE " & _

"[ThreadID] = " & mThreadID.ToString() & _ " ORDER BY PostDate DESC"

myData = DataControl.GetDataSet(sql)

list = New ArrayList()

Dim myRow As DataRow

For Each myRow In myData.Tables(0).Rows list.Add(myRow)

Next

End Sub

Public ReadOnly Property Count() As Integer

Get

Return list.Count

End Get

End Property

End Class

www.syngress.com

608 Chapter 13 • Creating a Message Board with ADO and XML

Just like ThreadList, PostList contains a Count property, a method to initialize posts in a thread, and a constructor that accepts the ID of the parent object.The only real difference here is that this class gets values from the User table instead of the Thread table. Next, let’s examine the Item function in Figure 13.35.

Figure 13.35 The Item Function (PostList.vb)

Public Function Item(ByVal index As Integer) As Post

Dim myObject As Object = list.Item(index)

If myObject.GetType() Is GetType(Post) Then

'it is already a post, so nothing further is needed

Else

Dim myPost As Post

myPost = New Post(CType(list.Item(index), DataRow)) 'replace the item in the list with

'an actual post object list.Item(index) = myPost

End If

Return CType(list.Item(index), Post)

End Function

In reviewing this Item function, note that it looks remarkably similar to the Item function in the ThreadList class. In fact, it is exactly the same except that it uses Post instead of Thread. Other than that difference, PostList is exactly the same as ThreadList.

Designing the Post Class

So far, you should have noticed most of the classes in our code share a lot of the same ideas: add, update, lists, mimicking the database tables.Well, the Post class is no different. In fact, it is rather similar to both the Board and Thread classes. Let’s take a look at the UML diagram for this class in Figure 13.36.

Just like the other classes, this one is remarkably similar to its brothers—espe- cially the Thread class.The only real difference between this class and the Thread class is that Post has a Body field, pulls its values from the Post table, and doesn’t have any child objects. Let’s take a look at the whole class in Figure 13.37 (which can be found on your CD as Post.vb), as there really isn’t much to it.

www.syngress.com

Creating a Message Board with ADO and XML • Chapter 13

609

Figure 13.36 The Post Class

Post

+ID : Long

+Subject : String

+Body : String

+Creator : User

+PostDate : Date

+Update()

Figure 13.37 Post.vb

Public Class

Post

 

Private

mPostID As Long

Private

mPostSubject

As String

Private

mPostBody As

String

Private

mCreator As

User

Private

mPostDate As

Date

Public Sub New(ByVal myRow As DataRow) inflate(myRow)

End Sub

Public Sub Update(ByVal requestor As User)

If requestor.ID = mCreator.ID Then

Dim sql As String

sql = "UPDATE [Posts] SET [PostSubject] = '" & _ mPostSubject & "', [PostBody] = '" & mPostBody & _ "' WHERE [PostID] = " & mPostID.ToString()

DataControl.ExecuteNonQuery(sql)

Else

Throw New ArgumentException _

("Only the creator of a post can update it")

End If

End Sub

Private Sub inflate(ByVal myRow As DataRow) mPostID = CLng(myRow("PostID"))

Continued

www.syngress.com