Skip to content

Commit d930c5b

Browse files
committed
fix(DocumentBuilder): handle HasMany relationships
1 parent 1b80f05 commit d930c5b

File tree

1 file changed

+40
-17
lines changed

1 file changed

+40
-17
lines changed

src/JsonApiDotNetCore/Builders/DocumentBuilder.cs

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -202,29 +202,52 @@ private List<DocumentData> GetIncludedEntities(List<DocumentData> included, Cont
202202

203203
var contextEntity = rootContextEntity;
204204
var entity = rootResource;
205-
206-
for(var i = 0; i < relationshipChain.Length; i++)
207-
{
208-
var requestedRelationship = relationshipChain[i];
209-
var relationship = contextEntity.Relationships.FirstOrDefault(r => r.PublicRelationshipName == requestedRelationship);
210-
var navigationEntity = _jsonApiContext.ContextGraph.GetRelationship(entity, relationship.InternalRelationshipName);
211-
if (navigationEntity is IEnumerable hasManyNavigationEntity)
212-
foreach (IIdentifiable includedEntity in hasManyNavigationEntity)
213-
included = AddIncludedEntity(included, includedEntity);
214-
else
215-
included = AddIncludedEntity(included, (IIdentifiable)navigationEntity);
216-
217-
if(i < relationshipChain.Length) {
218-
contextEntity = _jsonApiContext.ContextGraph.GetContextEntity(relationship.Type);
219-
entity = (IIdentifiable)navigationEntity; // HACK: only handles HasOne case ...
220-
}
221-
}
205+
included = IncludeRelationshipChain(included, rootContextEntity, rootResource, relationshipChain, 0);
222206
}
223207
}
224208

225209
return included;
226210
}
227211

212+
private List<DocumentData> IncludeRelationshipChain(
213+
List<DocumentData> included, ContextEntity parentEntity, IIdentifiable parentResource, string[] relationshipChain, int relationshipChainIndex)
214+
{
215+
var requestedRelationship = relationshipChain[relationshipChainIndex];
216+
var relationship = parentEntity.Relationships.FirstOrDefault(r => r.PublicRelationshipName == requestedRelationship);
217+
var navigationEntity = _jsonApiContext.ContextGraph.GetRelationship(parentResource, relationship.InternalRelationshipName);
218+
if (navigationEntity is IEnumerable hasManyNavigationEntity)
219+
{
220+
foreach (IIdentifiable includedEntity in hasManyNavigationEntity)
221+
{
222+
included = AddIncludedEntity(included, includedEntity);
223+
included = IncludeSingleResourceRelationships(included, includedEntity, relationship, relationshipChain, relationshipChainIndex);
224+
}
225+
}
226+
else
227+
{
228+
included = AddIncludedEntity(included, (IIdentifiable)navigationEntity);
229+
included = IncludeSingleResourceRelationships(included, (IIdentifiable)navigationEntity, relationship, relationshipChain, relationshipChainIndex);
230+
}
231+
232+
return included;
233+
}
234+
235+
private List<DocumentData> IncludeSingleResourceRelationships(
236+
List<DocumentData> included, IIdentifiable navigationEntity, RelationshipAttribute relationship, string[] relationshipChain, int relationshipChainIndex)
237+
{
238+
if(relationshipChainIndex < relationshipChain.Length)
239+
{
240+
var nextContextEntity = _jsonApiContext.ContextGraph.GetContextEntity(relationship.Type);
241+
var resource = (IIdentifiable)navigationEntity;
242+
// recursive call
243+
if(relationshipChainIndex < relationshipChain.Length - 1)
244+
included = IncludeRelationshipChain(included, nextContextEntity, resource, relationshipChain, relationshipChainIndex + 1);
245+
}
246+
247+
return included;
248+
}
249+
250+
228251
private List<DocumentData> AddIncludedEntity(List<DocumentData> entities, IIdentifiable entity)
229252
{
230253
var includedEntity = GetIncludedEntity(entity);

0 commit comments

Comments
 (0)