I have a situation here where the user has about 100 controls mostly multi select listboxes
but some other stuff peppered in (drop downs checkboxes) and they narrow down complex search criteria for screenings. When they go back later they want the act of pulling up a record to reset the controls to the values that they had used to match the criteria.
So I made a table that has a column for each control and iterativley stores the values - comma
deliminated for listboxes - when the user locks in the search criteria to move to the next step.
Other then using a switch to say if value is x: set control x to value(s) so and so is there a good way to iterate through this, seeing as the name of the column is the name of the control ? I'm stumped at the moment ...
var CParam = QueryFnc.RstrCntrls(Jnum, Qnum);
foreach(var a in CParam)
{
//Map Values to Matching Named Control
}
As long as your control tree remains constant, you can use control indices to map values. However better bet would be to use control IDs (if its .NET4 then go for predictable ids or manual id assignment for better controls) to map values.
Instead of storing values across columns in one row, I will prefer a table that will store values across rows. For example,
UserId ColumnName ControlID Value
------ ---------- --------- --------
1 ABC ddlAbc 52
1 XYZ ddlXyz 102, 32
...
2 XYZ ddlXyz 23
This will make things a lot simpler - get rows for the given user id and then iterate over rows. For each row, you can find the control using FindControl methods (you may have to roll up a recursive implementation in case you have naming containers in your control hierarchy) and then write simple switch statement to assign value to control based on control type.
You probably want to use reflection, and each control should have a factory method that inheits from a single interface, to allow for passing in the stored values.
With reflection you can find (and then instantiate) a control via it's name (as a string)
EDIT:
just thinking out loud here... You might also be able to use the chain of responsibility pattern, passing the name of the column along through your list of classes, and it is each objects responsibility to catch the name it is responsible for, and return an instance.
Related
I am wondering which method is the best way to store a list of integers in a sql column.
.....i.e. "1,2,3,4,6,7"
EDIT: These values represent other IDs in SQL tables. The row would look like
[1] [2]
id, listOfOtherIDs
The choices I have researched so far are:
A varchar of separated value that are "explode-able" i.e. by commas or tabs
An XML containing all the values individually
Using individual rows for each value.
Which method is the best method to use?
Thanks,
Ian
A single element of a record can only refer to one value; it's a basic database design principle.
You will have to change the database's design: use a single row for each value.
You might want to read up on normalization.
As is shown here in the description of the first normal form:
First normal form states that at every row and column intersection in the table there, exists a single value, and never a list of values. For example, you cannot have a field named Price in which you place more than one Price. If you think of each intersection of rows and columns as a cell, each cell can hold only one value.
While Jeroen's answer is valid for "multi-valued" attributes, there are genuine situations where multiple comma-separated values may actually be representing one large value. Things like path data (on a map), integer sequence, list of prime factors and many more could well be stored in a comma-separated varchar. I think it is better to explain what exactly are you storing and how do you need to retrieve and use that value.
EDIT:
Looking at your edit, if by IDs you mean PK of another table, then this sounds like a genuine M-N relation between this table and the one whose IDs you're storing. This stuff should really be stored in a separate gerund, which BTW is a table that would have the PK of each of these tables as FKs, thus linking the related rows of both tables. So Jeroen's answer very well suits your situation.
Please note that the database design I have now is fully in sandbox mode. Nothing is finalized. Everything (again this is in sandbox mode) is in one single table. Also, I'm in now way looking for coding help. I'm looking for the right theoretical/logical approach to this puzzle so I can go in and play with the coding myself. I learn better that way. If I need coding help, I'll come back here for further assistance.
I'm in the process of creating the first of a few CheckBoxList for a manually created form submittal. I've been looking over multiple ways to not only create said CheckBoxList but to enter it into the database. However, the challenge I'm facing (mainly because I haven't encountered this scenario before and I'd like to learn this) is that I not only need to worry about entering the items correctly in the database but I will eventually need to produce a report or make a printable form from these entries.
Let's say I have an order form for a specific type of Barbeque grill and I will need to send this form out to distriution centers across the nation. The distribution centers will need to pull said barbecues if they are highlighted on the form.
Here's what the CheckBoxList for the distibution centers will look like:
All
Dallas
Miami
Los Angeles
Seattle
New York
Chicago
Phoenix
Montreal
If the specific city (or all the cities) are checked, then the distribution center will pull the barbecue grill for shipment.
The added part is that I want to:
be able to create a grid view from this database for reporting to note which distribution center got orders for barbecues and
be able to create reports to tell what distribution center sent out barbecue orders in a given month (among other reporting).
Here's what I'm playing around with right now.
In my aspx page I have a checkboxlist programmed with all the distribution centers entered as a listitem as well as an option for 'ALL' (of the distribution centers).
I also created a dedicated column in this table that holds all the information in the listitem and programmed a sqldataconnection to this table to play with the programmability of leveraging the database for this purpose.
When it comes to writing the selections to the database, I originally created a column for each destination city including the 'All' option. I was toying around with just putting the selections into one single column but with some of the information I've been reading today about Database Normalization, the former options seems to be a better one than the latter. Is this correct practice for situations such as this especially if I need to think about reporting? Do I put the CheckBoxList data in one cell in a specific column? Do I create seprate columns for each distribution center? Am I even on the right track here?
Depending on the amount of cities that you want to store, I've used bitwise operators to store small amounts of data. Effectively, it would store it in the table like this:
CityID Location
2 Dallas
4 Miami
8 New York
16 Chicago
32 Montreal
and keep going in base 2 for additional cities.
When your user selects multiple cities for the order, the value that gets inserted into the database for cities is a bitwise OR calculation. So if they select Dallas, New York, and Chicago, you would be doing the following:
2 OR 8 OR 16
Which would equal 26
Now, you can use bitwise AND on the resulting value. So if checking for Miami the following is the evaluation:
26 AND 4 = 0
which indicates that Miami was not selected. Any value that was selected in the evaluation, it would return its ID like this:
26 AND 8 = 8
Again, I've only used this for small subsets of data, and to make the data storage as compact as possible. Computationally, it may be a trifle more expensive that some other methods, but I'm not 100% certain.
Note: This might not be the best approaches but I have seen them used.
1) Having one column of comma-delimited string
This should work well if the options don't have IDs in the database (having a separate referenced table)
You will need to loop through the checkbox list, obtained the selected options and concatenate them with String.Join()
You will need to split the string upon receiving it from the db and use it to check the checkboxes if there text is found in the resulting array
Problem: You might need a split function in the DB that converts the comma-separated string into rows. There split function implementation on the web/stackoverflow
2) You can have a separate table for the locations e.g. xxxxtable_location where the FK to the main table is referenced. This will be a one-many table
ParentID, Location
1 Dallas
2 Miami
2 New York
2 Chicago
3 Miami
So I have 70 "nodes" which are all textboxes in WPF and I'm trying to change the value in the textbox from a function call.
I have a function called:
private void changeNode(int row, int column, int cost)
{
int nodeNumber= row * 10 + column;
call node"nodeNumber".Text = Convert.String(cost);
//example node0.Text = Convert.String(cost);
}
I determine what node I want to change then call nodeX.Text to change it however I want X to be a variable that I can rather than having to create 70 cases where I call the appropriate textbox.
I saw a couple of ways of doing this with reflection however it seemed to only work if the function had no parameters and also was within the function not a textbox in XAML.
Let me know if there is a simple way to convert say a string "node37" to call node37.Text = cost or something like that.
Sounds like your approach is wrong. Why do you have a set of strings which represent the names of the textboxes? You should instead have in-memory references to TextBox objects. If you have more than one, and you don't know how many there will be, then use an array of TextBox objects instead. You can index into the array with the number that represents the textbox you're looking to interact with.
Avoid the use of reflection, it is completely unnecessary here.
I assume you have put names for all your textboxes (you can do this dynamically if you haven't). Then you can use the answers for this question to find the appropriate control by name.
Are all your textboxes children of the same canvas or other control? Loop through the children and add the controls to a dictionary. Parse the name to get the number and use that as the key.
It is always better to use List when you are dealing with Data. Create an ObservableCollection with the DataObjects which you want to load, and now deal with the Data object rather than actual Controls.
In WPF, if you follow the rules, you should not point to the actual object. Check the sample application here :
http://www.abhisheksur.com/2010/08/woring-with-icollectionviewsource-in.html
I think you will get the approach.
I have this problem and I don't know what is the best solution for it.
I have table called Employees and there is column called LastWork, this column should only have custom values I choose for example:
value 1
value 2
and I want the user to select the value from ComboBox control so I have 2 ideas for it but I don't know what is the best for it.
A - add these value to Combobox as string in Items property and store them as string in DB.
B - create separate table in my db called for example 'LastWork' with 2 columns 'LastWorkID', 'LastWorkName' and insert my values in it, and then I can add binding source control and I can use data bound items to store the id as integer in my main table and show the LastWorkName for users.
I prefer to use the B method because in some forms I have DataGridView control with edit permission, and I want to display Combobox in it instead of Textbox to select from these custom values.
I hope you understood my questions.
Normally data normalization is a good thing, so I too would go with your option B.
By having a separate table and a foreign key relationship to it, you can enforce data integrity; easily get a list of all available (not just all selected) options; have a single place in which to change the text of an option (what if someone decides to call it "value one" instead of "value 1", for example?); and so on and so forth.
These might not be huge benefits in a small application and with only two possible options, but we all know that applications very often tend to grow in scope over time.
In a normalized database, your "option B" is usually the way to go because it eliminates duplicate data. It will potentially introduce an additional join into your queries when you need the name (and not just the ID), but it also allows you to rename lookup names easily without altering their underlying IDs.
For performance reasons, it's often a good idea to cache lookup values such as you describe in the business tier so that your lookup table is not hit over and over again (such as when building many rows of a grid).
I would always save them in the db. If you have to localize your app, this helps alot. Additonally, it let you to apply the referential integrity checks of the database.
We're working on an hospital information system that is being written on C# and using NHibernate to map objects to database. MVC pattern is being used to separate business logic from UI. Here is the problem,
How do you get variable sized different set of strings to UI?
For example a Contact object have a property named City that holds which city contact lives. In country that the app is written for has more than 80 cities. How could you write those cities to a combo box? (or a data grid, tables, ...) In this example the city number is fixed. There is no need to add another city for a long time. (If the city list changes, recompiling is not a problem)
For example a Contact object have another property named FooBar which is going to be hold 1000 different string values and these values is going to be selected from a combo box for that property. And this set can be grown if users want. How do you load the combo box with these values? (If the string list statically written to combo box object, recompiling is a problem)
I have different solutions as below
All string values statically written to combo box in code or designer
Get the values from a resource file
Write those values to an XML file (Actually same as above, but no need to recompile)
Make a City object and get the values into a list from CITY table with NHibernate
Make a class named StringHolder which has a Type and Value property. All string values(including City and FooBar) would be written in just one table named STRINGHOLDER. And get those values with a key like "CITY" or "FOOBAR" with NHibernate.
Which one would you choose? Or could you suggest me another one?
Thanks all
I would vote for solution #4. That's the way I have always done it in similar situations. It just seems like a cleaner solution.
If the locations are actually going to be used for anything, get them into the database. If the data "isn't really used", but cities lookup is provided to make the user interface better, then the XML file option is not a bad way to go either.
By used, I mean stuff like list all emplyees in New York and stuff like that. If it's "dead data", just to be displayed, go for the solutions that will require the least amount of work and least risk - which might be the file option.
How do you feel of using List<string> for a list of City? Load this list of strings in your DAL or BL and then pass it on to UI.
Same solution should be good for FooBar values too.
In case you have IDs associated with City or FooBar, say NY and its numeric ID in DB is 1, then you can use KeyValuePair<TKey, TValue>. With generics you can dictate what data goes in this KeyValuePair. City name or FooBar's string value can be key and numeric ID can be value.
Just 2 cents.