@@ -13,9 +13,9 @@ public class DocumentBuilder : IDocumentBuilder
13
13
private readonly IJsonApiContext _jsonApiContext ;
14
14
private readonly IContextGraph _contextGraph ;
15
15
private readonly IRequestMeta _requestMeta ;
16
- private readonly DocumentBuilderOptions _documentBuilderOptions ;
16
+ private readonly DocumentBuilderOptions _documentBuilderOptions ;
17
17
18
- public DocumentBuilder ( IJsonApiContext jsonApiContext , IRequestMeta requestMeta = null , IDocumentBuilderOptionsProvider documentBuilderOptionsProvider = null )
18
+ public DocumentBuilder ( IJsonApiContext jsonApiContext , IRequestMeta requestMeta = null , IDocumentBuilderOptionsProvider documentBuilderOptionsProvider = null )
19
19
{
20
20
_jsonApiContext = jsonApiContext ;
21
21
_contextGraph = jsonApiContext . ContextGraph ;
@@ -143,34 +143,42 @@ private bool OmitNullValuedAttribute(AttrAttribute attr, object attributeValue)
143
143
private void AddRelationships ( DocumentData data , ContextEntity contextEntity , IIdentifiable entity )
144
144
{
145
145
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
+ {
146
156
var linkBuilder = new LinkBuilder ( _jsonApiContext ) ;
147
157
148
- contextEntity . Relationships . ForEach ( r =>
158
+ var relationshipData = new RelationshipData ( ) ;
159
+
160
+ if ( attr . DocumentLinks . HasFlag ( Link . None ) == false )
149
161
{
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 ) ;
151
165
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
+ }
157
169
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 ;
174
182
}
175
183
176
184
private List < DocumentData > GetIncludedEntities ( List < DocumentData > included , ContextEntity contextEntity , IIdentifiable entity )
@@ -240,23 +248,40 @@ private List<ResourceIdentifierObject> GetRelationships(IEnumerable<object> enti
240
248
var relationships = new List < ResourceIdentifierObject > ( ) ;
241
249
foreach ( var entity in entities )
242
250
{
243
- relationships . Add ( new ResourceIdentifierObject {
251
+ relationships . Add ( new ResourceIdentifierObject
252
+ {
244
253
Type = typeName . EntityName ,
245
254
Id = ( ( IIdentifiable ) entity ) . StringId
246
255
} ) ;
247
256
}
248
257
return relationships ;
249
258
}
259
+
250
260
private ResourceIdentifierObject GetRelationship ( object entity )
251
261
{
252
262
var objType = entity . GetType ( ) ;
263
+ var contextEntity = _jsonApiContext . ContextGraph . GetContextEntity ( objType ) ;
253
264
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 ,
258
268
Id = ( ( IIdentifiable ) entity ) . StringId
259
269
} ;
260
270
}
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
+
280
+ return new ResourceIdentifierObject
281
+ {
282
+ Type = relatedContextEntity . EntityName ,
283
+ Id = independentRelationshipIdentifier . ToString ( )
284
+ } ;
285
+ }
261
286
}
262
287
}
0 commit comments