Skip to content

Commit a6c6b25

Browse files
author
Caitlin Bales (MSFT)
committed
Add logic for returning implicit containment
Handles the case where a singleton has a navigation property that defines an implicit EntitySet using "ContainsTarget="true"". This allows us to generate code that correctly lets workloads navigate from a child object to a singleton's implicit EntitySet by $ref
1 parent 25dd44f commit a6c6b25

File tree

1 file changed

+37
-5
lines changed

1 file changed

+37
-5
lines changed

src/GraphODataTemplateWriter/Extensions/OdcmModelExtensions.cs

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -140,22 +140,54 @@ public static IEnumerable<OdcmMethod> GetMethods(this OdcmModel model)
140140
public static OdcmProperty GetServiceCollectionNavigationPropertyForPropertyType(this OdcmProperty odcmProperty)
141141
{
142142
// Try to find the first collection navigation property for the specified type directly on the service
143-
// class object. Use First() instead of FirstOrDefault() so template generation would fail if not found
144-
// instead of silently continuing. If an entity is used in a reference property a navigation collection
143+
// class object. If an entity is used in a reference property a navigation collection
145144
// on the client for that type is required.
146145
try
147146
{
148-
return odcmProperty
147+
var explicitProperty = odcmProperty
149148
.Class
150149
.Namespace
151150
.Classes
152151
.Where(odcmClass => odcmClass.Kind == OdcmClassKind.Service)
153152
.SelectMany(service => (service as OdcmServiceClass).NavigationProperties())
154153
.Where(property => property.IsCollection && property.Projection.Type.FullName.Equals(odcmProperty.Projection.Type.FullName))
155-
.First();
154+
.FirstOrDefault();
155+
156+
if (explicitProperty != null)
157+
return explicitProperty;
158+
159+
// Check the singletons for a matching implicit EntitySet
160+
else
161+
{
162+
var implicitProperty = odcmProperty
163+
.Class
164+
.Namespace
165+
.Classes
166+
.Where(odcmClass => odcmClass.Kind == OdcmClassKind.Service)
167+
.First()
168+
.Properties
169+
.Where(property => property.GetType() == typeof(OdcmSingleton)) //Get the list of singletons defined by the service
170+
.Where(singleton => singleton
171+
.Type
172+
.AsOdcmClass()
173+
.Properties
174+
//Find navigation properties on the singleton that are self-contained (implicit EntitySets) that match the type
175+
//we are searching for
176+
.Where(prop => prop.ContainsTarget == true && prop.Type.Name == odcmProperty.Type.Name)
177+
.FirstOrDefault() != null
178+
)
179+
.FirstOrDefault();
180+
181+
if (implicitProperty != null)
182+
return implicitProperty;
183+
}
184+
//If we are unable to find a valid EntitySet for the property, treat this
185+
//as an exception so the service has an opportunity to correct this in the metadata
186+
throw new Exception("Found no valid EntitySet for the given property.");
187+
156188
} catch (Exception e)
157189
{
158-
logger.Error("The navigation property \"{0}\" on class \"{1}\" does not specify it is self-contained nor is it defined in an EntitySet", odcmProperty.Name.ToString(), odcmProperty.Class.FullName.ToString());
190+
logger.Error("The navigation property \"{0}\" on class \"{1}\" does not specify it is self-contained nor is it defined in an explicit or implicit EntitySet", odcmProperty.Name.ToString(), odcmProperty.Class.FullName.ToString());
159191
logger.Error(e);
160192
return null;
161193
}

0 commit comments

Comments
 (0)