@@ -13,9 +13,9 @@ public class DocumentBuilder : IDocumentBuilder
1313 private readonly IJsonApiContext _jsonApiContext ;
1414 private readonly IContextGraph _contextGraph ;
1515 private readonly IRequestMeta _requestMeta ;
16- private readonly DocumentBuilderOptions _documentBuilderOptions ;
16+ private readonly DocumentBuilderOptions _documentBuilderOptions ;
1717
18- public DocumentBuilder ( IJsonApiContext jsonApiContext , IRequestMeta requestMeta = null , IDocumentBuilderOptionsProvider documentBuilderOptionsProvider = null )
18+ public DocumentBuilder ( IJsonApiContext jsonApiContext , IRequestMeta requestMeta = null , IDocumentBuilderOptionsProvider documentBuilderOptionsProvider = null )
1919 {
2020 _jsonApiContext = jsonApiContext ;
2121 _contextGraph = jsonApiContext . ContextGraph ;
@@ -143,34 +143,42 @@ private bool OmitNullValuedAttribute(AttrAttribute attr, object attributeValue)
143143 private void AddRelationships ( DocumentData data , ContextEntity contextEntity , IIdentifiable entity )
144144 {
145145 data . Relationships = new Dictionary < string , RelationshipData > ( ) ;
146+ contextEntity . Relationships . ForEach ( r =>
147+ data . Relationships . Add (
148+ r . PublicRelationshipName ,
149+ GetRelationshipData ( r , contextEntity , entity )
150+ )
151+ ) ;
152+ }
153+
154+ private RelationshipData GetRelationshipData ( RelationshipAttribute attr , ContextEntity contextEntity , IIdentifiable entity )
155+ {
146156 var linkBuilder = new LinkBuilder ( _jsonApiContext ) ;
147157
148- contextEntity . Relationships . ForEach ( r =>
158+ var relationshipData = new RelationshipData ( ) ;
159+
160+ if ( attr . DocumentLinks . HasFlag ( Link . None ) == false )
149161 {
150- var relationshipData = new RelationshipData ( ) ;
162+ relationshipData . Links = new Links ( ) ;
163+ if ( attr . DocumentLinks . HasFlag ( Link . Self ) )
164+ relationshipData . Links . Self = linkBuilder . GetSelfRelationLink ( contextEntity . EntityName , entity . StringId , attr . PublicRelationshipName ) ;
151165
152- if ( r . DocumentLinks . HasFlag ( Link . None ) == false )
153- {
154- relationshipData . Links = new Links ( ) ;
155- if ( r . DocumentLinks . HasFlag ( Link . Self ) )
156- relationshipData . Links . Self = linkBuilder . GetSelfRelationLink ( contextEntity . EntityName , entity . StringId , r . PublicRelationshipName ) ;
166+ if ( attr . DocumentLinks . HasFlag ( Link . Related ) )
167+ relationshipData . Links . Related = linkBuilder . GetRelatedRelationLink ( contextEntity . EntityName , entity . StringId , attr . PublicRelationshipName ) ;
168+ }
157169
158- if ( r . DocumentLinks . HasFlag ( Link . Related ) )
159- relationshipData . Links . Related = linkBuilder . GetRelatedRelationLink ( contextEntity . EntityName , entity . StringId , r . PublicRelationshipName ) ;
160- }
161-
162- var navigationEntity = _jsonApiContext . ContextGraph
163- . GetRelationship ( entity , r . InternalRelationshipName ) ;
164-
165- if ( navigationEntity == null )
166- relationshipData . SingleData = null ;
167- else if ( navigationEntity is IEnumerable )
168- relationshipData . ManyData = GetRelationships ( ( IEnumerable < object > ) navigationEntity ) ;
169- else
170- relationshipData . SingleData = GetRelationship ( navigationEntity ) ;
171-
172- data . Relationships . Add ( r . PublicRelationshipName , relationshipData ) ;
173- } ) ;
170+ // this only includes the navigation property, we need to actually check the navigation property Id
171+ var navigationEntity = _jsonApiContext . ContextGraph . GetRelationship ( entity , attr . InternalRelationshipName ) ;
172+ if ( navigationEntity == null )
173+ relationshipData . SingleData = attr . IsHasOne
174+ ? GetIndependentRelationshipIdentifier ( ( HasOneAttribute ) attr , entity )
175+ : null ;
176+ else if ( navigationEntity is IEnumerable )
177+ relationshipData . ManyData = GetRelationships ( ( IEnumerable < object > ) navigationEntity ) ;
178+ else
179+ relationshipData . SingleData = GetRelationship ( navigationEntity ) ;
180+
181+ return relationshipData ;
174182 }
175183
176184 private List < DocumentData > GetIncludedEntities ( List < DocumentData > included , ContextEntity contextEntity , IIdentifiable entity )
@@ -240,23 +248,42 @@ private List<ResourceIdentifierObject> GetRelationships(IEnumerable<object> enti
240248 var relationships = new List < ResourceIdentifierObject > ( ) ;
241249 foreach ( var entity in entities )
242250 {
243- relationships . Add ( new ResourceIdentifierObject {
251+ relationships . Add ( new ResourceIdentifierObject
252+ {
244253 Type = typeName . EntityName ,
245254 Id = ( ( IIdentifiable ) entity ) . StringId
246255 } ) ;
247256 }
248257 return relationships ;
249258 }
259+
250260 private ResourceIdentifierObject GetRelationship ( object entity )
251261 {
252262 var objType = entity . GetType ( ) ;
263+ var contextEntity = _jsonApiContext . ContextGraph . GetContextEntity ( objType ) ;
253264
254- var typeName = _jsonApiContext . ContextGraph . GetContextEntity ( objType ) ;
255-
256- return new ResourceIdentifierObject {
257- Type = typeName . EntityName ,
265+ return new ResourceIdentifierObject
266+ {
267+ Type = contextEntity . EntityName ,
258268 Id = ( ( IIdentifiable ) entity ) . StringId
259269 } ;
260270 }
271+
272+ private ResourceIdentifierObject GetIndependentRelationshipIdentifier ( HasOneAttribute hasOne , IIdentifiable entity )
273+ {
274+ var independentRelationshipIdentifier = hasOne . GetIdentifiablePropertyValue ( entity ) ;
275+ if ( independentRelationshipIdentifier == null )
276+ return null ;
277+
278+ var relatedContextEntity = _jsonApiContext . ContextGraph . GetContextEntity ( hasOne . Type ) ;
279+ if ( relatedContextEntity == null ) // TODO: this should probably be a debug log at minimum
280+ return null ;
281+
282+ return new ResourceIdentifierObject
283+ {
284+ Type = relatedContextEntity . EntityName ,
285+ Id = independentRelationshipIdentifier . ToString ( )
286+ } ;
287+ }
261288 }
262289}
0 commit comments