CSLA : Step-by-Step , Relationships

Due to popular demand…ok…just Phil … we’re back with the second installment of CSLA: Step-by-Step.
In the previous tutorial, we took a look at how to setup the various tools and templates to easily generate your first CSLA business object.
In this tutorial we’ll dive a little deeper into parent-child objects, and which CSLA object to use where.
The Relationship
For this example we’ll generate an Order object that has a collection of Order Details.
We’ll create the following classes:
Order (BusinessBase)
OrderDetail (BusinessBase)
OrderDetails (BusinessListBase)
Start by starting up CodeSmith and opening the EditableRoot.cst template. Fill in the property grid, to look like this:

Copy the generated code, create a new class in your NorthwindTraders project, called Orders, and paste the code. Next generate the stored procedures using MyGeneration.
You’ll notice that the compiler complains that OrderDetails are not defined on this line:
Private _orderdetails As OrderDetails = OrderDetails.NewOrderDetails()
We’ll get to that in a moment. Next, let’s generate the OrderDetail object. In CodeSmith open the EditableChild.cst template. Fill in the property grid to look like this:
Again, copy and paste the code in a class called OrderDetail.
You’ll notice the following comment in the AddInsertParameters sub:
‘todo: If parent use identity key, fix fk member with value from parent
Change this line:
cm.Parameters.AddWithValue("@OrderID", _orderID)
To this:
cm.Parameters.AddWithValue("@OrderID", parent.OrderID)
This is important so that the parent’s id is cascaded to the child object.
OK,so next we need to generate the OrderDetails class, that the compiler complained about. Using CodeSmith again open the EditableChildList.cst template and change the property grid to look like this:
Create the OrderDetails.vb class in your project and paste the generated code. The compiler should stop complaining about the OrderDetails object.
Allrighty. Now, we’ve got our Order Object and the Order Details collection(of Order Detail). We also have the stored procedures for the Order object, BUT just how will we get the Order Details? You’ll notice that in the Order Detail’s fetch method there is nothing about which stored proc to use. Not to worry.
You’ll notice that in the Order object’s ExecuteFetch method the FetchChildren sub is called. In this sub there is only 2 lines of code:
dr.NextResult()
_orderdetails = OrderDetails.GetOrderDetails(dr)
Now, in order for the datareader to actually read the NextResult we need to alter the Order object’s select stored procedure to also get the Order Details for the Order. Fire up your favourite query editor and change the Order’s select stored proc to look like this:
SELECT *
FROM [Orders] WITH (NOLOCK)
WHERE
[OrderID] \= @OrderID
SELECT *
FROM [Order Details] WITH (NOLOCK)
WHERE
[OrderID] \= @OrderID
This query will return 2 result sets, that’s the reason we need to use dr.NextResult. So with this one query you will automatically load the order and it’s child detail records. Cool huh?
Ok, so let’s recap. We’ve created a parent object named Order, a child object called OrderDetail and a collection of OrderDetail, called OrderDetails. We’ve changed the parent Order object’s stored procedure to also select the related child objects. And we’re ready to test our code.
Just as in part 1, let’s add the unit test code:
Namespace UnitTests
_
Public Class OrderUnitTests
Dim OrderID As Integer
Dim objOrder As Order
_
Protected Sub SetUpTest()
OrderID = 10248
objOrder = Order.GetOrder(OrderID)
End Sub
_
Public Sub FetchOrderChildren()
Assert.IsTrue(objOrder.Orderdetails.Count = 3, "Failed to get customer")
End Sub
End Class
End Namespace
You can test using TestDriven or the NUnit Gui. My test failed at first and I had to change this line in the OrderDetail class:
_discount = dr.GetDecimal("Discount")
To:
_discount = dr.Item("Discount")
And there you go! If your Order object return 3 Order Details, you know it’s working!
That concludes Part 2, I hope it was useful, please feel free to give your comments. In part 3, we’ll look at troubleshooting your objects and frequent errors as well as some more object integration.
Thanks for reading, I’ll chat to you soon.






