Skip to content

Commit 8a69eff

Browse files
committed
refactor(DocumentBuilder): dont lookup resource on graph multiple times
1 parent 6fc162f commit 8a69eff

File tree

2 files changed

+22
-14
lines changed

2 files changed

+22
-14
lines changed

src/JsonApiDotNetCore/Builders/DocumentBuilder.cs

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ public class DocumentBuilder : IDocumentBuilder
1818
private readonly IScopedServiceProvider _scopedServiceProvider;
1919

2020
public DocumentBuilder(
21-
IJsonApiContext jsonApiContext,
22-
IRequestMeta requestMeta = null,
21+
IJsonApiContext jsonApiContext,
22+
IRequestMeta requestMeta = null,
2323
IDocumentBuilderOptionsProvider documentBuilderOptionsProvider = null,
2424
IScopedServiceProvider scopedServiceProvider = null)
2525
{
@@ -112,7 +112,8 @@ public ResourceObject GetData(ContextEntity contextEntity, IIdentifiable entity)
112112

113113
public ResourceObject GetData(ContextEntity contextEntity, IIdentifiable entity, IResourceDefinition resourceDefinition = null)
114114
{
115-
var data = new ResourceObject {
115+
var data = new ResourceObject
116+
{
116117
Type = contextEntity.EntityName,
117118
Id = entity.StringId
118119
};
@@ -177,9 +178,8 @@ private RelationshipData GetRelationshipData(RelationshipAttribute attr, Context
177178
relationshipData.Links.Related = linkBuilder.GetRelatedRelationLink(contextEntity.EntityName, entity.StringId, attr.PublicRelationshipName);
178179
}
179180

180-
// this only includes the navigation property, we need to actually check the navigation property Id
181+
// this only includes the navigation property, we need to actually check the navigation property Id
181182
var navigationEntity = _jsonApiContext.ContextGraph.GetRelationshipValue(entity, attr);
182-
183183
if (navigationEntity == null)
184184
relationshipData.SingleData = attr.IsHasOne
185185
? GetIndependentRelationshipIdentifier((HasOneAttribute)attr, entity)
@@ -196,14 +196,14 @@ private List<ResourceObject> GetIncludedEntities(List<ResourceObject> included,
196196
{
197197
if (_jsonApiContext.IncludedRelationships != null)
198198
{
199-
foreach(var relationshipName in _jsonApiContext.IncludedRelationships)
199+
foreach (var relationshipName in _jsonApiContext.IncludedRelationships)
200200
{
201201
var relationshipChain = relationshipName.Split('.');
202202

203203
var contextEntity = rootContextEntity;
204204
var entity = rootResource;
205205
included = IncludeRelationshipChain(included, rootContextEntity, rootResource, relationshipChain, 0);
206-
}
206+
}
207207
}
208208

209209
return included;
@@ -214,7 +214,7 @@ private List<ResourceObject> IncludeRelationshipChain(
214214
{
215215
var requestedRelationship = relationshipChain[relationshipChainIndex];
216216
var relationship = parentEntity.Relationships.FirstOrDefault(r => r.PublicRelationshipName == requestedRelationship);
217-
var navigationEntity = _jsonApiContext.ContextGraph.GetRelationship(parentResource, relationship.InternalRelationshipName);
217+
var navigationEntity = _jsonApiContext.ContextGraph.GetRelationship(parentResource, relationship.InternalRelationshipName);
218218
if (navigationEntity is IEnumerable hasManyNavigationEntity)
219219
{
220220
foreach (IIdentifiable includedEntity in hasManyNavigationEntity)
@@ -227,23 +227,23 @@ private List<ResourceObject> IncludeRelationshipChain(
227227
{
228228
included = AddIncludedEntity(included, (IIdentifiable)navigationEntity);
229229
included = IncludeSingleResourceRelationships(included, (IIdentifiable)navigationEntity, relationship, relationshipChain, relationshipChainIndex);
230-
}
230+
}
231231

232232
return included;
233233
}
234234

235235
private List<ResourceObject> IncludeSingleResourceRelationships(
236236
List<ResourceObject> included, IIdentifiable navigationEntity, RelationshipAttribute relationship, string[] relationshipChain, int relationshipChainIndex)
237237
{
238-
if (relationshipChainIndex < relationshipChain.Length)
238+
if (relationshipChainIndex < relationshipChain.Length)
239239
{
240240
var nextContextEntity = _jsonApiContext.ContextGraph.GetContextEntity(relationship.Type);
241241
var resource = (IIdentifiable)navigationEntity;
242242
// recursive call
243-
if(relationshipChainIndex < relationshipChain.Length - 1)
243+
if (relationshipChainIndex < relationshipChain.Length - 1)
244244
included = IncludeRelationshipChain(included, nextContextEntity, resource, relationshipChain, relationshipChainIndex + 1);
245245
}
246-
246+
247247
return included;
248248
}
249249

@@ -289,7 +289,11 @@ private List<ResourceIdentifierObject> GetRelationships(IEnumerable<object> enti
289289
var relationships = new List<ResourceIdentifierObject>();
290290
foreach (var entity in entities)
291291
{
292-
typeName = _jsonApiContext.ContextGraph.GetContextEntity(entity.GetType()).EntityName;
292+
// this method makes the assumption that entities is a homogenous collection
293+
// so, we just lookup the type of the first entity on the graph
294+
// this is better than trying to get it from the generic parameter since it could
295+
// be less specific than what is registered on the graph (e.g. IEnumerable<object>)
296+
typeName = typeName ?? _jsonApiContext.ContextGraph.GetContextEntity(entity.GetType()).EntityName;
293297
relationships.Add(new ResourceIdentifierObject
294298
{
295299
Type = typeName,
@@ -304,7 +308,7 @@ private ResourceIdentifierObject GetRelationship(object entity)
304308
var objType = entity.GetType();
305309
var contextEntity = _jsonApiContext.ContextGraph.GetContextEntity(objType);
306310

307-
if(entity is IIdentifiable identifiableEntity)
311+
if (entity is IIdentifiable identifiableEntity)
308312
return new ResourceIdentifierObject
309313
{
310314
Type = contextEntity.EntityName,

src/JsonApiDotNetCore/Internal/ContextGraph.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ public interface IContextGraph
1818
/// <code>
1919
/// _graph.GetRelationship(todoItem, nameof(TodoItem.Owner));
2020
/// </code>
21+
/// <remarks>
22+
/// This method will not work with HasManyThrough relationships.
23+
/// You should instead use the <see cref="GetRelationshipValue" /> method instead.
24+
/// </remarks>
2125
/// </example>
2226
object GetRelationship<TParent>(TParent resource, string propertyName);
2327

0 commit comments

Comments
 (0)