I'm starting to come to grips with this n-tier stuff using the data mapper pattern etc and have come across the following problem. From reading the other threads I think I'm getting confused because I am thinking about the problem from the database up, rather
than the application down, but anyway... If I use a foreign key relationship as follows: e.g. my application deals with Members, so I have a member class, a member mapper class and a member table in the database. Now I want to categorise my members by Member
Type, so I have a Member Type table in the database and you can set the Member Type field of the Member to be a specific Member Type. So in my member class how do I handle the Member Type? The fact that it is stored in another table is not really relevant
at the class level because it becomes basically a mechanism to limit the users choices. Therefore I don't think I need a Member Type class, at least not inside the Member class. The datatype is essentially an array of strings with one currently selected. But
if this is a good approach what interface would I present to the UI layer to represent this? Of course the part of the application that allows modification of Member Types will required a Member Type class. My thinking so far has led me to think that I would
need to handle it as a datatype inside the Member class and as a Member Type class in its own right, which somehow seems inconsistent to me? Anyway that is my ramblings on the subject, can anyone point me to the correct pattern to use (and maybe even explain
it). Cheers
:: The fact that it is stored in another table is not really :: relevant at the class level because it becomes basically a :: mechanism to limit the users choices. Ummm, I'd say its relavent, since a run-time list kind of eliminates the enum option.
public class Member
public ???? MemberType { get; set; }
So your question is, what should the type be for the
MemberType property in your Member class?
Well, I'd say string is the worse choice. Enum might be
a possiblity if your system never allowed the MemberType
table to be modified (or you have some mechanism to
sync-up table changes to your code base). But I think
the best choice is to have another class (or struct) for
your MemberType table.
How many columns does it have? Sounds like a code
table, and the most common code-table set-up is with
two columns: CODE (used as PK) and DESCRIPTION
(what the user sees).
So you'd have...
public class Member
public MemberType MemberType { get; set; }
public class MemberType
public string Code { get; set; }
public string Description { get; set; }
And some example business logic...
Member m = new Member();
m.MemberType = MemberType.DefaultFactory.RetrieveByCode("A");
OK, I think I'm with you there... So a Member class would have an instance of a MemberType class... My UI then displays MemberType.Description ... But the UI wants to allow the MemberType to be changed and therefore needs to display a ListBox containing the
available MemberTypes (Descriptions). Where does the UI get this list from? From Member? If so what kind of interface? The UI needs to be able to: - Read & Display the current MemberType - Provide all MemberTypes so that changes can be made - Tell Member what
the new MemberType is after editing
This is the pattern I use for any code-table that appears as a drop-down list on the UI. You need one method on the factory which returns a collection of rows with 2 columns, one column for the PK value, the other column for user text that's placed in the drop-down
list.
public class CodeTableFactory
public string[][] GetListing
{
get
{
string[][] rows = this.connection.Execute("select PK, USER_TEXT from CODE_TABLE");
return rows;
}
}
Then the drop-down list control will call this method. I use SQL instead of a collection of objects because drop-down lists sometimes want to display the text for each item in funky ways. Take a State code-table. The users may want to see the State abbreviation code and the name of the state in the drop-down...
TN - Tennesse
TX - Texas
...so its not always as simple as a single object property like codeTable.Description. And SQL seems a better way to format this text then with objects.
The drop-down needs the PK value for each item in the list so that once a user selects an item, the control can use the PK to get the real CodeTable object and assign it to the BusinessEntity that references it.
"...so its not always as simple as a single object property like codeTable.Description. And SQL seems a better way to format this text then with objects. " What's wrong with the following ;)
public class State
{
private string _abbreviation;
private string _name;
public string Name
{
get { return _name; }
}
public string Abbreviation
{
get { return _abbreviation; }
}
public string NameAndAbbreviation
{
get { return String.Format("{0} - {1}", _abbreviation, _name); }
}
}
"Can't sleep, clowns will eat me... can't sleep clowns will eat me, can't sleep clowns will eat me"
That will work. But a couple of things. First of all, this user-text is something specific to the UI layer. Drop-downs on different pages for the same code-table may want to format it differently. So if you're going to use objects, just have the factory return
a collection of all objects from the database, and then let the UI iterate through them and format the text for the user to see. There's really no need to cluter the State BLL with formatting properties that are only being used by the UI. But I still perfer
SQL over objects because I've had some wierd user requests. What they want to see in the drop-down is not always from the same table. So instead of getting a collection of object-graphs, I just find SQL to be more direct and natural. But either way works and
its probably just a matter of taste. Btw, since we're talking about advanced code-tables, let's not forget that drop-downs which limit their set of values based on some other value on the screen. Parent/Child objects do this alot. The Child entity has a code-table
reference, but the values it can choose are limited by a property in the Parent. If the user types in the parent value first, then when they go to the Child property's drop-down, you can limit the set of values to choose from.
Cool... I guess you could have a factory (data-access) class that returns a mapper class (if one had reason to have multiple mappers, or would you have the factory (data-access) class use its another factory (mapper) class and hide all that from the UI? Am
I even making sense I ask myself :)
Returns a mapper class? Multiple mapper classes, at the same time? That's crazy talk. The purpose of the factory is to hide the mapper (or whatever your data-access technique is) from the UI. UI --> Factory (BLL) -->Mapper (DAL) --> SQL-Server (Data-Store).
CoolKiwiBlok...
Participant
789 Points
173 Posts
Foreign Key Pattern
Jul 19, 2004 11:13 PM|LINK
Gabe Halsmer
Participant
880 Points
176 Posts
Re: Foreign Key Pattern
Jul 20, 2004 12:51 AM|LINK
public class Member public ???? MemberType { get; set; }So your question is, what should the type be for the MemberType property in your Member class? Well, I'd say string is the worse choice. Enum might be a possiblity if your system never allowed the MemberType table to be modified (or you have some mechanism to sync-up table changes to your code base). But I think the best choice is to have another class (or struct) for your MemberType table. How many columns does it have? Sounds like a code table, and the most common code-table set-up is with two columns: CODE (used as PK) and DESCRIPTION (what the user sees). So you'd have...public class Member public MemberType MemberType { get; set; } public class MemberType public string Code { get; set; } public string Description { get; set; }And some example business logic...Member m = new Member(); m.MemberType = MemberType.DefaultFactory.RetrieveByCode("A");CoolKiwiBlok...
Participant
789 Points
173 Posts
Re: Foreign Key Pattern
Jul 20, 2004 12:16 PM|LINK
Gabe Halsmer
Participant
880 Points
176 Posts
Re: Foreign Key Pattern
Jul 20, 2004 04:43 PM|LINK
public class CodeTableFactory public string[][] GetListing { get { string[][] rows = this.connection.Execute("select PK, USER_TEXT from CODE_TABLE"); return rows; } }Then the drop-down list control will call this method. I use SQL instead of a collection of objects because drop-down lists sometimes want to display the text for each item in funky ways. Take a State code-table. The users may want to see the State abbreviation code and the name of the state in the drop-down... TN - Tennesse TX - Texas ...so its not always as simple as a single object property like codeTable.Description. And SQL seems a better way to format this text then with objects. The drop-down needs the PK value for each item in the list so that once a user selects an item, the control can use the PK to get the real CodeTable object and assign it to the BusinessEntity that references it.public void dropDown_OnUserSelect() { string stateCode = (string)dropDown.Keys[ dropDown.SelectedIndex ]; address.State = stateFactory.RetrieveByStateCode( stateCode ); }n1ckP
Member
650 Points
130 Posts
Re: Foreign Key Pattern
Jul 20, 2004 05:37 PM|LINK
public class State { private string _abbreviation; private string _name; public string Name { get { return _name; } } public string Abbreviation { get { return _abbreviation; } } public string NameAndAbbreviation { get { return String.Format("{0} - {1}", _abbreviation, _name); } } }Nick Patterson
Systems Architect
Gabe Halsmer
Participant
880 Points
176 Posts
Re: Foreign Key Pattern
Jul 20, 2004 08:44 PM|LINK
CoolKiwiBlok...
Participant
789 Points
173 Posts
Re: Foreign Key Pattern
Jul 20, 2004 09:19 PM|LINK
Gabe Halsmer
Participant
880 Points
176 Posts
Re: Foreign Key Pattern
Jul 21, 2004 03:55 AM|LINK
CoolKiwiBlok...
Participant
789 Points
173 Posts
Re: Foreign Key Pattern
Jul 21, 2004 01:16 PM|LINK
Gabe Halsmer
Participant
880 Points
176 Posts
Re: Foreign Key Pattern
Jul 21, 2004 03:36 PM|LINK