Some context: this refers to my aspiring desire to create layered web applications with:
- C # ASP.NET Web Forms
- C # POCO Business Objects
- Some kind of DAL ... SQL (or maybe EF4, if I can understand it)
I would not want the answer on which my view layer spoke directly to EF objects, for example.
I have been doing my own web development with C # ASP.NET and SQL for 10 years, but I'm still a newbie when it comes to formal OOAD. I've been pursuing this skill lately, but I'm still new to this and I can't completely wrap my head. I hope someone can explain this in such a way as to bring insight:
Let's say I'm creating a web application that somehow manages People , and my Person object must have properties such as FirstName, LastName, HairColor, EyeColor, Ethnicity, StateOrProvince, etc. m using SQL Server to save ... so common sense will determine that the corresponding fields in the People table are foreign keys:
FirstName varchar(50) LastName varchar(50) HairColor tinyint EyeColor tinyint Ethnicity tinyint StateOrProvince tinyint
Obviously, this means that I have corresponding search tables for each of these fields (for example, HairColors table, EyeColors table, Ethnicity table, etc.), and each of these search tables has an identifier and a name. Of course, the Name field in these lookup tables will be JOINed with my People data when I want to display something useful about Person.
Some key features of the site:
1.) List people in Gridview (FirstName, LastName, HairColor, EyeColor, Ethnicity, StateOrProvince)
2.) Show individual Character data on a read-only page (FirstName, LastName, HairColor, EyeColor, Ethnicity, StateOrProvince)
3.) Allow the user to update individual Person data on the update page (FirstName, LastName, HairColor, EyeColor, Ethnicity, StateOrProvince)
Case # 1 If I were listing a collection of Person objects in a gridview ... each Person instance would have to display its HairColor, EyeColor, Ethnicity, StateOrProvince properties as strings to make sense (that is, the Name field from the SQL lookup table, not the identifier ) Obviously, my SQL sproc would have several JOINs to provide me with the appropriate string data needed to populate these text properties in each Person instance.
Case # 2 Again, my sproc would have a JOIN to return human readable property names as strings , and I would only display them in read mode. Label controls use something like myPerson.HairColor, myPerson.EyeColor, etc.
Case No. 3 Here I would show a page with drop-down lists for each of these properties (i.e. Value = HairColorId, Text = HairColorName). My immediate instinct here would be to use the identifiers of each property (something like myPerson.HairColorId) to iterate over the DDL elements and select a value that represents the hair color that is currently in the People table for that person. If the user selects something else in any of the DDL properties, I need to pass the corresponding SelectedId values to the UPDATE sproc and change the values in the People table for this particular Person.
So this leads me to the final question:
The best way is to create a Person object so that it contains both an ID and a name for HairColor, EyeColor, Ethnicity, StateOrProvince, so I can subsequently use the Name when displaying , but the identifier to initialize the DDL controls of the update ... and, ultimately processing updates ?
As I was thinking about this ... I came to the conclusion that I need to create classes to represent the properties HairColor, EyeColor, Ethnicity, StateOrProvince.
Then the Person class, and not something like this:
public class Person { string FirstName { get; set; } string LastName { get; set; } int HairColorId { get; set; } string HairColorName { get; set; } int EyeColorId { get; set; } string EyeColorName { get; set; } int StateOrProvinceId { get; set; } string StateOrProvinceName { get; set; } string StateOrProvinceCode { get; set; } }
Instead, something like this will be expanded:
public class HairColor { int Id { get; set; } string Name { get; set; } } public class EyeColor { int Id { get; set; } string Name { get; set; } } public class StateOrProvince { int Id { get; set; } string Name { get; set; } string Code { get; set; } } public class Person { HairColor HairColor { get; set; } EyeColor EyeColor { get; set; } StateOrProvince StateOrProvince { get; set; } public Person() {
But then, if the Person class looks like the one shown above ... what is the best way to initialize it (whether individually or in a collection) from this data string, do I return from the SQL query? I seem to remember that I should not introduce new things into the constructor (ie This.HairColor = new HairColor (dr ["HairColorId"), dr ["HairColorName"];) ... so I wonder like a challenge
public static IEnumerable<Person> GetPeople() { ... }
in my BLL can each user fill out his data before he is added to the collection?
Really hope someone can give me a “ha” moment here ...