@@ -33,6 +33,7 @@ public async Task<List<Operation>> ProcessAsync(List<Operation> inputOps)
3333 {
3434 var outputOps = new List < Operation > ( ) ;
3535 var opIndex = 0 ;
36+
3637 using ( var transaction = await _dbContext . Database . BeginTransactionAsync ( ) )
3738 {
3839 try
@@ -63,8 +64,8 @@ private async Task ProcessOperation(Operation op, List<Operation> outputOps)
6364 {
6465 var operationsPointer = new OperationsPointer ( ) ;
6566
66- ReplaceDataPointers ( op . DataObject , outputOps ) ;
67- // ReplaceRefPointers (op.Ref, outputOps);
67+ ReplaceLocalIdsInResourceObject ( op . DataObject , outputOps ) ;
68+ ReplaceLocalIdsInRef ( op . Ref , outputOps ) ;
6869
6970 var processor = GetOperationsProcessor ( op ) ;
7071 var resultOp = await processor . ProcessAsync ( op ) ;
@@ -73,43 +74,56 @@ private async Task ProcessOperation(Operation op, List<Operation> outputOps)
7374 outputOps . Add ( resultOp ) ;
7475 }
7576
76- private void ReplaceDataPointers ( DocumentData data , List < Operation > outputOps )
77+ private void ReplaceLocalIdsInResourceObject ( ResourceObject resourceObject , List < Operation > outputOps )
7778 {
78- if ( data == null ) return ;
79-
80- bool HasLocalId ( ResourceIdentifierObject rio ) => string . IsNullOrEmpty ( rio . LocalId ) == false ;
81- string GetIdFromLocalId ( string localId ) {
82- var referencedOp = outputOps . FirstOrDefault ( o => o . DataObject . LocalId == localId ) ;
83- if ( referencedOp == null ) throw new JsonApiException ( 400 , $ "Could not locate lid '{ localId } ' in document.") ;
84- return referencedOp . DataObject . Id ;
85- } ;
86-
87- // are there any circumstances where the primary data would contain an lid?
88- // if(HasLocalId(data))
89- // {
90- // data.Id = GetIdFromLocalId(data.LocalId);
91- // }
92-
93- if ( data . Relationships != null )
79+ if ( resourceObject == null ) return ;
80+
81+ // it is strange to me that a top level resource object might use a lid.
82+ // by not replacing it, we avoid a case where the first operation is an 'add' with an 'lid'
83+ // and we would be unable to locate the matching 'lid' in 'outputOps'
84+ //
85+ // we also create a scenario where I might try to update a resource I just created
86+ // in this case, the 'data.id' will be null, but the 'ref.id' will be replaced by the correct 'id' from 'outputOps'
87+ //
88+ // if(HasLocalId(resourceObject))
89+ // resourceObject.Id = GetIdFromLocalId(outputOps, resourceObject.LocalId);
90+
91+ if ( resourceObject . Relationships != null )
9492 {
95- foreach ( var relationshipDictionary in data . Relationships )
93+ foreach ( var relationshipDictionary in resourceObject . Relationships )
9694 {
9795 if ( relationshipDictionary . Value . IsHasMany )
9896 {
9997 foreach ( var relationship in relationshipDictionary . Value . ManyData )
10098 if ( HasLocalId ( relationship ) )
101- relationship . Id = GetIdFromLocalId ( relationship . LocalId ) ;
99+ relationship . Id = GetIdFromLocalId ( outputOps , relationship . LocalId ) ;
102100 }
103101 else
104102 {
105103 var relationship = relationshipDictionary . Value . SingleData ;
106104 if ( HasLocalId ( relationship ) )
107- relationship . Id = GetIdFromLocalId ( relationship . LocalId ) ;
105+ relationship . Id = GetIdFromLocalId ( outputOps , relationship . LocalId ) ;
108106 }
109107 }
110108 }
111109 }
112110
111+ private void ReplaceLocalIdsInRef ( ResourceReference resourceRef , List < Operation > outputOps )
112+ {
113+ if ( resourceRef == null ) return ;
114+ if ( HasLocalId ( resourceRef ) )
115+ resourceRef . Id = GetIdFromLocalId ( outputOps , resourceRef . LocalId ) ;
116+ }
117+
118+ private bool HasLocalId ( ResourceIdentifierObject rio ) => string . IsNullOrEmpty ( rio . LocalId ) == false ;
119+
120+ private string GetIdFromLocalId ( List < Operation > outputOps , string localId )
121+ {
122+ var referencedOp = outputOps . FirstOrDefault ( o => o . DataObject . LocalId == localId ) ;
123+ if ( referencedOp == null ) throw new JsonApiException ( 400 , $ "Could not locate lid '{ localId } ' in document.") ;
124+ return referencedOp . DataObject . Id ;
125+ }
126+
113127 private IOpProcessor GetOperationsProcessor ( Operation op )
114128 {
115129 switch ( op . Op )
0 commit comments