BuildChildCallbacks() of ProjectRepository: childkey, child keys, foriegnkeys like contracts/contacts ...

Oct 2, 2013 at 11:40 AM
Edited Oct 2, 2013 at 12:16 PM
Dear Tim McCarthy!

Great thanks for doing great job. My question related to childkeys (of ChildCallbacks dictionary) which is set from inside ProjectRepository Class, as below.
    protected override void BuildChildCallbacks()
    {
        this.ChildCallbacks.Add(ProjectFactory.FieldNames.OwnerCompanyId, 
            this.AppendOwner);
       ...
    }
I learn from the book that these dictionary keys are Foriegn Keys. Therefore, in ProjectRepository, we set OwnerCompanyId as childCallbacks dictionary key (as OwnerCopmanyID is column in "Project" table and its value come from primary key CopmanyID in "Company" table). Same is true for ConstructionAdministratorEmployeeId, and PrincipalEmployeeId for the employees to be part/attribute of Project class. So far so good.

But, i am unable to understand why do you have "allowances", "contracts", "contacts" as keys in ChildCallbacks? where do we get them from ? I am not able to find any such column in Project Table and not even in any other tables.

I assume that consider that in IDataReader the columns "allowances", "contracts" and "contacts" are alias names for some columns of the tables in a JOIN SQL Statement. Is that correct?

If answer to above question is "yes" then this leads to the point that in order to call (delegate) appendContracts(), i shall need a Join Query on tables "Project" and "Contracts" with ContractId alias as "contracts"? so that IDataReader.getSchemaTable() return DataTable Column "Contracts" as the Alias Name for the "ContractID" column of the table "Contracts" so as to match with childCallbacks dictionary key "Contracts".

For example, this.AppendContracts(project) in the code below will be called only if DataTable returned from IDataReader.getSchemaTable() will contain "contracts" as column name of DataTable (resulting from SQL).
        this.ChildCallbacks.Add("contracts",
            delegate(Project project, object childKeyName)
            {
                this.AppendContracts(project);
            });
If the answer is yes then in terms of database operations will not it be heavy operation like calling DB table twice as: 1) Join Query on Projects and Contracts with "ContractID" in list of select columns 2) in the appendContracts() function, query the Contracts table again just to fetch all the records matching Project.Key; ?
    private void AppendContracts(Project project)
    {
        StringBuilder builder = new StringBuilder(100);
        builder.Append("SELECT * FROM Contract");
        __builder.Append(string.Format(" WHERE ProjectID = '{0}'", project.Key));__
        using (IDataReader reader = this.ExecuteReader(builder.ToString()))
        {
            while (reader.Read())
            {
                project.Contracts.Add(ProjectFactory.BuildContract(reader));
            }
        }
    }
I am looking for your answer on above.

Regards,
Oct 2, 2013 at 1:52 PM
Answer to this question is that

If any of the keys in ChildCallbacks dictionary is found to be in the column of DataTable of Project then Project is the child Entity/table of another Entity/Table and key is a foriegn key of parent table. If the key is not matched with column in Data Table then it means key defined childCallbacks dictionary is not a FK of some other entity instead Project is the parent of the entity/table to which deinfed key belongs hence null is passed and key is used only to call the delegate and the value of key is passed as null to the delegate.

Therefore, we can say that ProjectRepository defines keys as FKs (through which Project Entity gets its data as well as keys through which a delegate is called to populate objects from ChildTable.