Because we are facing some tight deadlines we are on out way of reducing as much of the repetitive code in our forms as possible.
In most forms what we have is a grid that has some columns on it plus some textboxes or combos, each of which holds the data referenced in the selected row of the grid.
What we have there is essentially something like:
EntityCollection allPFV = new EntityCollection(new PFV1EntityFactory());
...
ultraGridPFV.DataSource = allPFV;
When the user selects a given record of the datagrid the data is saved in a currentPF that's a PFEntity.
The mapping is then done to and from the entity to some combos and other needed components on the form.
In order to avoid Form's locking problems related derived from the Form running in a single thread we make each of these operations for each of the entities that we need to load data for, in a different thread.
As the binding code tends to be quite similar when we do the initialization of the form we pass in an array with the relevant information for each of the the components in the form along with the fields of the db from which we are going to read the data.
Continuing with the example above, once a record is selected what we use is it's ID, which is an ID because we set it as one on the designer. Remember the grid is built on a view hence it has no ID really.
That ID allows us to load the data from the table holding the data which in the above example would be PFEntity. Note it is not a PFVEntity, meaning by our naming convention it is not a view.
In general in the database if we have a table called TAB, it's PK will be named ID_TAB. A FK in a table called FTAB towards the table TAB will be again named ID_TAB. The problem appears when the table FTAB has two references toward the table TAB. In this case we call the first FK towards TAB ID_TAB1 and the second one ID_TAB2.
When doing the mappings and the validations one of the things we need to know is the name of the field that is a PK in the table TAB referenced by the field FTAB.ID_TAB2. We could then use that ID for the binding to the value property of the combo that will display it's data. For most of the fields as the name of the field is the same as the one in the FTAB we of course have no problem...
Right now one of the things we pass the binding, valdating, loading methods is the field on the table FTAB and we pass it as being of type EntityField2.
We do something like:
gf = new VaVGenericField( ref _bwdlRSVFull1XEntity, "RSVFull1", new RSVFullEntityFactory(), "DescripcionCompleta", PFFields.IdAS1,"IdActvsub1",
ref ultraComboEditorActividadSubactividad1, true); formFields.Add(gf);
then that is actually building a class with a constructor like this one:
public VaVGenericField(
ref BackgroundWorker entityDataLoaderBackgroundWorker, //the background worker that will load the data
String fieldName, //a name for the field, not used in the model itself, just in error messages and logging
IEntityFactory2 FieldEntityFactory, //the entity that is going to be loaded
String DisplayField, //the field that is shown on the combo
EntityField2 Field, // the field on the core entity upon which is built the view that is shown on the grid
String DataFieldOnGrid, //the name of column on the grid
ref UltraComboEditor UltraComboEditor, // the combo that is going to get/set the data of this field
bool LimitToList //set to false if user can enter new values on this combo
) {
...
Right now we are solving the problem by looking for the PK of the table from which we fill the combo:
xFieldEntityFactory = FieldEntityFactory;
...
pkFieldOnRefrencedTable = xFieldEntityFactory.Create().PrimaryKeyFields[0];
But it would be a lot nicer to be able to write up something that would get the PK at which the FK field Field is actually pointing to, by looking just at the <EntityField2> Field.
Not sure if I managed to explain myself clear enough