Mike Lorengo has an interesting post about binding gridviews in ASP .NET 2.0 to “complex” objects. I have already posted a short reply to his blog and wish to elaborate upon it here.
To start with, let me say that I am a huge fan of using objects inherited from CollectionBase over datasets. Objects to me are simply more flexible and make more sense. However, it is very easy to get caught up in the ease and "neatness" factor of databinding your complex objects.
Consider the following scenario. You have two objects called Category and Subcategory. A category is a top level describer which contains zero to many subcategories. For the purposes of simplicity we'll examine only the subcategory object which will contain a lazy loaded property reference to category. In a typical lazy loading scenario you'll end up with an object that looks something like this:
1 public class Subcategory
2 { 3 #region private members
4
5 //property accessors
6 private int _subcategoryid = -1;
7 private int _categoryid;
8 private string _subcategoryname;
9 private Category _category;
10
11 //Database key
12 private string _connectstring;
13
14 #endregion private members
15
16 #region Properties
17
18 public int SubCategoryID
19 { 20 get
21 { 22 return _subcategoryid;
23 }
24 set
25 { 26 _subcategoryid = value;
27 }
28 }
29
30 public int CategoryID
31 { 32 get
33 { 34 return _categoryid;
35 }
36 set
37 { 38 _categoryid = value;
39 }
40 }
41
42 public string SubCategoryName
43 { 44 get
45 { 46 return _subcategoryname;
47 }
48 set
49 { 50 _subcategoryname = value;
51 }
52 }
53
54 public Category Category
55 { 56 get
57 { 58 if(_category == null)
59 _category = new Category(_categoryid, _connectstring);
60
61 return _category;
62 }
63 }
64
65 #endregion Properties
Now in Mike's scenario if you wanted to display a grid with a list of Subcategories and their category names you would simply access the Category property of Subcategory which would check to see if it was populated and if not load it by id. One thing to be mindful of is that the application has already made a database call to get the subcategories and now may end up making additional calls to load the subobjects for subcategory. Instead of one query you end up with 1 + (NumberOfRows * NumberOfComplexProperties) calls. You can see how as you bound objects that contained references to many other objects you could quickly end up with a ton of database calls which damages your performance and scalability.
The solution? Either expose inital load methods that make the huge database call and prepopulate the referenced objects in one shot
or (my preferred method)
A more efficient way to display summary information is to expose domain level queries that execute single sql statements and return datatables. If you need to go from that summary down to specific items you have access to the keys and can load the individual objects as needed.