@@ -137,6 +137,14 @@ public string GetPostAsyncMethod(OdcmProperty odcmProperty, string requestBody =
137137
138138public string GetImplicitNavigationPropertyUrlSegment(OdcmSingleton singleton, OdcmProperty odcmProperty)
139139{
140+ /****
141+ To help the future dev in figuring this out, put a break point on the next executable line
142+ with the condition odcmProperty.Name == "teachers". The CSDL in and entities mentioned in these
143+ comments are an example of the use of this scenario.
144+
145+ ****/
146+
147+
140148 // (1) Check that there are NavigationPropertyBindings. If there aren't any, then we know this segment of
141149 // the canonical path to the reference.
142150 if (singleton.NavigationPropertyBindings.Count == 0)
@@ -145,13 +153,13 @@ public string GetImplicitNavigationPropertyUrlSegment(OdcmSingleton singleton, O
145153 }
146154
147155 // (2) Get all of the keys that contain our target path name. The keys come from the Path attribute on a
148- // NavigationPropertyBinding. So if our target property (OdcmProperty.Name) is named 'schools ', then we need to only consider
149- // NavigationPropertyBinding paths that end with 'schools '. The NavigationPropertyBindings are found in the Singleton that
156+ // NavigationPropertyBinding. So if our target property (OdcmProperty.Name) is named 'teachers ', then we need to only consider
157+ // NavigationPropertyBinding paths that end with 'teachers '. The NavigationPropertyBindings are found in the Singleton that
150158 // defines the EntitySet that contains this property. The NavigationPropertyBindings provide generation hints for how to
151159 // reference non-contained entities that are defined within the same Singleton (this statement is conjecture). This generation
152160 // hints is used to specify a reference URL for $ref call.
153161
154- // TODO DELETE : in this case, "teachers". This should be the end part of the BindingPath.
162+ // Example : in this case, "teachers". This should be the end part of the BindingPath.
155163
156164 IEnumerable<string> keys = singleton.NavigationPropertyBindings.Where(kvp => kvp.Key.EndsWith(odcmProperty.Name)).Select(kvp => kvp.Key);
157165 /*
@@ -164,18 +172,50 @@ public string GetImplicitNavigationPropertyUrlSegment(OdcmSingleton singleton, O
164172 <NavigationPropertyBinding Path="users/schools" Target="schools" />
165173 <NavigationPropertyBinding Path="users/classes" Target="classes" />
166174 </Singleton>
175+
176+ <EntityType Name="educationRoot" BaseType="microsoft.graph.entity">
177+ <NavigationProperty Name="synchronizationProfiles" Type="Collection(microsoft.graph.educationSynchronizationProfile)" ContainsTarget="true" />
178+ <NavigationProperty Name="classes" Type="Collection(microsoft.graph.educationClass)" ContainsTarget="true" />
179+ <NavigationProperty Name="schools" Type="Collection(microsoft.graph.educationSchool)" ContainsTarget="true" />
180+ <NavigationProperty Name="users" Type="Collection(microsoft.graph.educationUser)" ContainsTarget="true" />
181+ <NavigationProperty Name="me" Type="microsoft.graph.educationUser" ContainsTarget="true" />
182+ </EntityType>
183+
184+ <EntityType Name="educationClass" BaseType="microsoft.graph.entity">
185+ <Property Name="displayName" Type="Edm.String" Nullable="false" />
186+ <NavigationProperty Name="schools" Type="Collection(microsoft.graph.educationSchool)" />
187+ <NavigationProperty Name="members" Type="Collection(microsoft.graph.educationUser)" />
188+ <NavigationProperty Name="teachers" Type="Collection(microsoft.graph.educationUser)" />
189+ <NavigationProperty Name="group" Type="microsoft.graph.group" />
190+ <NavigationProperty Name="assignments" Type="Collection(microsoft.graph.educationAssignment)" ContainsTarget="true" />
191+ </EntityType>
167192 */
168193
169194 // We need to support long NavPropBindings. That is, we need to support multi-segment NavigationPropertyBinding paths
170195 // (3) We need to query the paths in {keys} against the entity (odcmProperty.Class) that contains this navigation property (odcmProperty).
171196 // We need to determine the unique binding path from the singleton through the entity on to this navigation property, query the keys
172- // for it, and then get the target. There could be 1 or more hops that we need to account for.
197+ // for it, and then get the target. There could be 1 or more pat segments that we need to account for.
198+ // Example: odcmProperty.Class is the entity "educationClass" that has the non-contained navigation property represented by odcmProperty,
199+ // which is named 'teachers'. At this point, we know the singleton and all of its NavigationPropertyBindings, we know the singleton's entity type,
200+ // which is named 'educationRoot'.
201+ // We need to determine whether a NavigationPropertyBinding pth and target is different than the CSDL described path to the reference non-contained entity.
173202
174203 // odcmProperty.Name; // --> "teachers"
175204
176205 var navPropClassToFind = odcmProperty.Class.Name; // -- > "educationClass"; This is the EntityType that contains the navigation property
177206 string firstBindingPathSegment = ""; // We are incorrectly assuming to segment.
178207
208+ // Get the path segments.
209+ //string[] navPropBindingSegments = keys.First().Split('/');
210+
211+ // Example: After hitting the conditional breakpoint, singleton.Type.Name is "educationRoot".
212+ // We are going to inspect each navigation property on singleton's type and compare to the segments
213+ // in the keys IEnumerable.
214+ // The assumption here is that the first segment is a navigation property of the singleton's type
215+ // The second assumption is that there are only two segments. We know this is a bad assumption.
216+ // The third assumption is that the last segment is the most meaningful.
217+ // In short, this only works for a Path that has two segments.
218+
179219 foreach (OdcmProperty prop in (singleton.Type as OdcmEntityClass).Properties)
180220 {
181221 if (prop.Type.Name == navPropClassToFind)
@@ -185,6 +225,32 @@ public string GetImplicitNavigationPropertyUrlSegment(OdcmSingleton singleton, O
185225 }
186226 }
187227
228+ /*
229+ What we know.
230+
231+ We know the navigation property name and type.
232+ We know whih entity contains the navigation property.
233+ We know that the navigation property does not contain the entity.
234+ We know which singleton is the entity set for the navigation property.
235+ We know the singleton's type.
236+ We know the NavigationPropertyBindings and which candidates CAN be the one to define the reference path to the entity in the navigation.
237+
238+ We don't know the paths to the entity that contains our navigation property. So, the question is, can we know the context in which the
239+ navigation property is being accessed at generation time? I don't think we can.
240+
241+ The next question is can we code the templates to generate code that is context aware and can create the ref path based on that context.
242+ This is a maybe.
243+
244+ Our current example works since the scenario only has two levels of entities. What happens when we have three level of entities like
245+ /schools/classes/teachers. We know the teachers segments. We don't have context which entities are accessed across the request builders
246+ at runtime.
247+
248+ We may need to generate a dictionary from the NavPropBindings in to the code files and use those at runtime to discover the context in
249+ which a navigtion is called in order to provide the correct reference path.
250+
251+ TODO: investigate what it would take to generate code that is context aware of binding path.
252+ */
253+
188254 string secondBindingPathSegment = odcmProperty.Name;
189255
190256 //string bindingPath = firstBindingPathSegment + "/" + keys.First(); // TODO: Need to fix this.
0 commit comments