Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Make a Master/Detail DGV using CSLA DynamicRootList - Part I

0.00/5 (No votes)
13 Mar 2009 1  
This project shows how to have a master/detail DataGridView using CSLA EditableRootListBase (or DynamicRootList) as the master list object. It shows how to have sorted list and auto save on both the master and detail DataGridView.
Fig. Screenshot of Warehouse DGV

1. Introduction

CSLA is a free 3-tier framework for .NET Framework 2.0, 3.0 and 3.5. CslaGen is a code generator for CSLA. About CSLA and CslaGen, refer to How to Use CslaGen to Generate CSLA Data Access Layer Code.

This project was born when I was trying to prove that it couldn't be done. Well... you know, it happens all the time. :)

It shows how to have a master/detail DataGridView (DGV for short) using CSLA DynamicRootList or EditableRootListBase (ERLB for short) as the master list object. If you use ERLB for the master list, auto save is a standard feature. This project also shows how to implement auto save on the detail list. As a bonus, you get both lists sorted.

This project shows a detailed example of a CslaGen project with all major issues discussed. CslaGen doesn't support DynamicRootList generation as we speak (March 2009). Also as a bonus, you can see the changes you need to do in order to transform CslaGen object types EditableRootCollection + EditableSwitchable into proper CSLA DynamicRootList + DynamicRoot.

1.1. Technical Stuff

  • CslaGen doesn't have version numbers. I use a slightly customized version (including changed template files) that you can download here.
  • The solution includes CSLA 3.0.5 object code under the References folder.
  • The solution builds under .NET Framework 2.0 and Visual Studio 2008.
  • Microsoft SQL Server 2005 was used in this project, but you can also use the Express version.

2. Background

CSLA framework has different kinds of objects and EditableRootListBase (or DynamicRootList) was the last one to join the framework. It was designed with the sole purpose of data binding with Windows Forms DGV. Under CSLA, objects follow some guidelines. I will point out only the ones that are relevant for this project:

  • Root objects are the only kind of objects that are loaded and saved on their own.
  • Child objects are loaded and saved by their parent (be it root or another child object).
  • Usually a child object doesn't have a reference to its parent (and shouldn't need it).
  • ERLB is an exception to the general principle since it's a root object (root list) made of root objects.
  • You can find more details on the Glossary of Common Terms.
  • An EditableRootList is a list of objects. Those objects must be child objects. Suppose you have a list of employees as an EditableRootList. Every employee would be an EditableChild. Once you edit employee data (employee is a child object), in order to save it, you must save the whole employee list (the root). This isn't a practical proposition. Usually what you do is have a root read only list of all employees that allows you to choose the one you want to edit as a root object (an independent object, not a child of the root read only list). But this isn't the way DGV works. So a new breed of objects was born:
    • EditableRootListBase, a root collection of root objects
  • ERLB is a root collection that loads objects but that allows you to save each one separately, i.e. each object in the collection is a root object. That matches the behavior of DGV that saves each row as soon as you move to another row.

    2.1. What's In A Name?

    It took me some trouble to understand the "not so common terms" but this issue is not as trivial as you could think, since it reveals important things about ERLB. CSLA templates now include a DynamicRootList as well as a DynamicRoot. As mentioned before, we know DynamicRootList is another name for ERLB. But what about DynamicRoot? Why can't we use the EditableRoot template? In fact ERLB uses root objects, but not common editable root objects because they are loaded like an editable child is loaded. It turns out that CslaGen object type EditableSwitchable can be loaded both as an editable root and editable child. As we will see later, using CslaGen object types EditableRootCollection + EditableSwitchable is the closest thing to DynamicRootList + DynamicRoot generation since it requires only small changes to get the job done.

    For simplicity sake, from now on we will use only DynamicRootList and will drop the names EditableRootListBase and ERLB. Likewise we will only use DynamicRoot and will drop EditableRoot.

    3. Other Points of Interest

    Most people turn to ProjectTracker for examples of CSLA use. Besides a comprehensive example of DynamicRootList, this article offers a different source of use examples. You may find these examples interesting:

    • use of SortedBindingList to sort the DataGridView
    • use of AddBusinessRules with the new syntax
    • use of System.Threading.Interlocked.Decrement to get unique temporary IDs for new objects
    • optimistic concurrency and DataPortal events (both standard in CslaGen)
    • complete CslaGen project documentation with all less obvious options discussed (refer to the Appendix for a complete collection of screen shots)

    4. Use Cases

    For this example project, I chose the subject "Brands & Models". Each brand is the parent of several models and no model is child of two brands. There can be no two brands with the same name. For a given brand, there can be no two models with the same name although the same model name may exist on different brands. Note that name match is case insensitive.

    As I intended to make this re-usable, at the UI (User Interface) level, the names are all around "master" and "detail". At BO (Business Objects) level, I use the real object names. In order to re-use it, you just need to replace BrandColl, Brand, ModelColl and Model with your own object names. To make it even more re-usable, you should make it a Component.

    5. The Database

    The database Warehouse has a table for brands and another for models. BrandID is the foreign key for models table.

    Fig. 1 - Warehouse database diagram
    Fig. 1 - Warehouse database diagram.

    The Price column is defined as money under SQL Server. For .NET Framework the data type used is Decimal.

    CslaGen supports optimistic concurrency automatically if you include a SQL column of timestamp data type. In spite of its name, this data type isn't time related at all but is really a version count starting at zero and increasing whenever there is a row update. That's why I prefer to call it RowVersion. Optimistic concurrency checks if the present row version matches the row version at the time the object was fetched and if it doesn't, it refuses to save, warning you that the object has changed. This means some other user has changed or deleted it.

    Under SQL Server run the scripts to create the database and the tables. While you are at it, also run the scripts to create the stored procedures. The project file CslaERLB1.zip includes all the scripts. You will populate the database yourself using the compiled sources.

    6. The Objects

    Although CslaGen doesn't support DynamicRootList (yet), a CslaGen file (Warehouse.xml) is included in CslaERLB1.zip. I used the CslaGen object types EditableRootCollection and EditableSwitchable. Then I made some changes to the generated files and transform the set into a proper set of DynamicRootList + DynamicRoot objects (CSLA template naming).

    Fig. 2 - Warehouse object diagram
    Fig. 2 - Warehouse object diagram (only non generated objects are visible).

    BrandColl is a root collection of Brand objects. It's a DynamicRootList, a collection made of DynamicRoot objects. So Brand is also a root object. Brand object is the parent of ModelColl collection and ModelColl is a collection of Model objects.

    NOTES

    • The Nested Types are the criteria for the object.
    • The static field _lastID is used as a seed for temporary ID, before new objects are committed to the database and acquire the real ID (as supplied by the database).
    • The AddBusinessRules method is responsible for adding the validation rules to the object. CslaGen has some support for validation rules. But I really prefer to do it myself. In this case, it uses the new syntax (since CSLA 2.1).
    • The NoDuplicates method is a validation rule that checks the name doesn't exist in the collection according to the rules explained in 4. Use cases.
    • In order to use DGV, each collection must have an AddNewCore method.

    Other Parts of this Article

    History

    • Document version 1: 12 March 2009
    • Code version 1.1: 14 March 2009 - bug correction
  • License

    This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

    A list of licenses authors might use can be found here