jonwagner/Insight.Database — pull request #179 by kevinsea (2014-12-23 04:43:26+00:00)
Title: Feature/childmapping

Here are the proposed code changes to improve Parent-Child mapping as discussed in Issue 169 in the main repo.

TL;DR the changes look pretty extensive, but much is mechanical refactoring to expose existing functionality for reuse.

Documentation would now read:

To determine the Parent's ID field, Insight uses the following order of precedence:
1. The field(s) explicitly requested in the structure definition's id parameter.
2. The field(s) on the parent class marked with the `[RecordId]` attribute.
3. A field called "ID".
4. A field called "_ID", e.g. Beer_ID for class Beer. (v5.X or higher)
5. A field called "ID", e.g. BeerID for class Beer. (v5.X or higher)
6. A field ending in "_ID", e.g. Brewski_ID for class Beer. (v5.1.1 or higher)
7. A field ending in "ID", e.g. BrewskiID. for class Beer.

To determine a Child's ParentID field, Insight uses the following order of precedence:
1. The field(s) explicitly requested in the structure definition's GroupBy clause.
2. The field(s) on the child class marked with the [ParentRecordId] attribute.
3. A field called "ParentID".
4. A field ending in "_ParentID".	(v5.1.1 or higher)
5. A field ending in "ParentID".
6. The Parent class's ID field(s) if they all exist in the child class. (v5.X or higher)
7. If none of the above, assume the fields are not in the child class, and grab enough fields to match the number of fields in the Parent class's ID field.

Thoughts on reviewing the code; the commits flow like this:

Commit 1: Initial set of unit tests on GetIDAccessor and FindParentIDAccessor as the the changes are contained inside these methods. The only interesting thing here is the shim added for unit testing.

Commit 2: Mechanical refactors via resharper, these should be very safe...they are noisy change wise. The trick here was separating the IDAccessor creation from the work of getting the list of properties in an ID. (I needed the former to implement Child rule # 6). I added more tests based on the refactors.

Commit 3: Implementing the features (the 5.x rules above). The feature coding is pretty small as most of the logic was already present. See FindParentIDAccessor and InferParentIDAccessorFromParentClass for the feature code. Much of the rest of the effort in this iteration was pushing the exception creation up to GetIDAccessor level so the Finds would not throw exceptions. More units were added to ensure the exception behavior was unchanged. I also added some functional tests to demonstrate the new automatching capabilities (these tests re marked with comment ///New Functionality). ParentID resolution was also refined and separated from primary ID resolution based on your earlier comments and other issues uncovered during testing.