Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

PROPER way to fill drop-downs from classes?

Status
Not open for further replies.

mddittman

Programmer
Sep 3, 2003
5
US
I would like to hear some input on the proper way to build classes so I can fill controls such as dropdown boxes in the proper way in C#.

Right now I have objects that can be contained by collection classes (such as Customer and Customers). The Customers object's constructor takes the ID of another object that has Customer objects (such as a Business) and fills the collection in this manner:

A. First, do a query to get a list of Customer IDs that are associated with the Business.
B. Once I have that list, I loop through, create a new Customer and add it to the collection, i.e.
Code:
while (dr.Read())
{
  List.Add(new Customer(customerID));
}

Each Customer constructor queries the database to return a fully populated existing Customer.

My problem is when I want to come up with a list of Customer.Name's and Customer.ID's for every existing customer so I can use them in a bound list, such as a drop-down list box! The way I see it, I have two choices:

A. "Cheat" and query the database directly to populate the list box from the GUI code. One hit to the database, minimal overhead, but is not OOP.
B. Loop through all Customers and create a separate Customer object for each one, even though all I need is the .Name and .ID of each one. Seems like the right "OOP" thing to do, but if you have 200 Customers, that's 200 separate database hits instead of one!

I thought about passing a dataset to the Customer object via another constructor, but I'd like to keep the Customer completely encapsulated.

Am I missing another way? What is the commonly accepted OOP way to tackle this problem?

Thanks for your advice...
 
First off, let me say I'm no OO guru, so take what I suggest with a grain of salt.

If your only options are A and B, then I say go with A, for performance reasons.

But it seems to me that you'll probably face this scenario again for some other kind of object, using the same or some other database.

So...why not create a utility class that does the single db hit with a method which has input parameters for db name, user id, password, etc - and of course, maybe this could be done just by specifying the name of a configuration file that has this information and the file name is an input parameter - as well as the name of the table, the name of the 'ID/data value' column, and the name of the 'description/name/display value' column? The method returns a collection of say, 'NameID' objects, where 'NameID' is just a simple class with instance variables and methods for name and ID. Another method would take the collection of 'NameID' objects and return the HTML for a SELECT listbox containing said 'NameID' objects.

Just my $0.02.
 
There seems to be a rising number of posts asking about OOD. That’s a good thing. [wink]

Some if not most of them are looking for the one correct design. The thing is, it doesn’t exist at the project level. Each project comes with a unique set of goals, criteria, restrictions, requirements, dependencies etc. These could all factor into what a decent design will be for that project.

Perhaps the best way to start getting a grasp of OOD is to study Software Patterns:


-pete
 
OR, you could retrieve a dataset from the database and use databinding to populate the list. You could still use 3-tier architecture (Presentation, Logic, Data), and you wouldn't have to create 200 individual customer objects.

Even if you wanted to do the customer-object way, I woudln't hit the database 200 times! Way too much overhead. Again, it would be better to use the dataset to retrieve all 200 records, and manipulate that in code.

Overall though, I'm more of a fan of the first option I suggested.

Hey, btw (you may have already posted this there, but just in case), we do have some great .NET forums here at Tek-Tips. If you're doing web development, head over to teh ASP.NET forum, or we also have a pretty good C# forum as well.

hth

D'Arcy
 
Thanks everyone for your input. Here's how I ended up doing this:

Changed the stored proc to allow the CustomerID to be optional. If the CustomerID is null, it returns all Customers, else the specific Customer that belongs to the ID.

In my Customers collection class, I allow the user to make an empty Customers collection using a blank constructor, then I added a public method LoadAllCustomers. This creates a dataset of all information from all Customers. I then loop through the dataset, and create a new Customer object for each row and add it to the Customers collection. The only change to the Customer object was the addition of another constructor that takes the DataRow as a parameter, then the Customer is populated on those values rather than hitting the database for values.

I don't really NEED all the other field info for each customer, but at least it's there if I need it, it keeps non-OOP code out of my GUI project and uses only one hit to the database!

Hope this helps anyone else with this problem!
 
Although you have already solved your problem, let me give you my view of it.

You have two classes:
Code:
Customer
as a member class and
Code:
Customers
as a collection class.

Filling the combobox is typically the responsibility of the
Code:
Customers
collection. So the
Code:
Customers
collection would have a
Code:
fillCombobox(cbo:ComboBox)
method. How this method is "driven" is still open.
A query is definitely not a bad idea here, as you probably do not want to load all the objects that are associated with the query.
Another possibility is to use so called "proxy objects": Objects that are initialized in two stages: a lightweight stage for just showing their identity and a full blown one if they are really used in the program. This is usually too much work if you just want to fill a combobox list.

The
Code:
Customer
member class does not need to know anything about the combobox list.

Best regards
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top