@@ -199,9 +199,7 @@ private void AttachHasManyPointers(TEntity entity)
199199 private void AttachHasMany ( HasManyAttribute relationship , IList pointers )
200200 {
201201 foreach ( var pointer in pointers )
202- {
203202 _context . Entry ( pointer ) . State = EntityState . Unchanged ;
204- }
205203 }
206204
207205 private void AttachHasManyThrough ( TEntity entity , HasManyThroughAttribute hasManyThrough , IList pointers )
@@ -218,14 +216,48 @@ private void AttachHasManyThrough(TEntity entity, HasManyThroughAttribute hasMan
218216 _context . Entry ( pointer ) . State = EntityState . Unchanged ;
219217
220218 var throughInstance = Activator . CreateInstance ( hasManyThrough . ThroughType ) ;
221- _context . Entry ( throughInstance ) . State = EntityState . Added ;
222-
223219 hasManyThrough . LeftProperty . SetValue ( throughInstance , entity ) ;
224220 hasManyThrough . RightProperty . SetValue ( throughInstance , pointer ) ;
221+
225222 throughRelationshipCollection . Add ( throughInstance ) ;
226223 }
227224 }
228225
226+ private void UpdateHasManyThrough ( TEntity entity )
227+ {
228+ var relationships = _jsonApiContext . HasManyRelationshipPointers . Get ( ) ;
229+ foreach ( var relationship in relationships )
230+ {
231+ if ( relationship . Key is HasManyThroughAttribute hasManyThrough )
232+ {
233+ // create the collection (e.g. List<ArticleTag>)
234+ // this type MUST implement IList so we can build the collection
235+ // if this is problematic, we _could_ reflect on the type and find an Add method
236+ // or we might be able to create a proxy type and implement the enumerator
237+ var throughRelationshipCollection = Activator . CreateInstance ( hasManyThrough . ThroughProperty . PropertyType ) as IList ;
238+ hasManyThrough . ThroughProperty . SetValue ( entity , throughRelationshipCollection ) ;
239+ foreach ( var pointer in relationship . Value )
240+ {
241+ _context . Entry ( pointer ) . State = EntityState . Unchanged ;
242+
243+ var throughInstance = Activator . CreateInstance ( hasManyThrough . ThroughType ) ;
244+ _context . Entry ( throughInstance ) . State = EntityState . Added ;
245+
246+ hasManyThrough . LeftIdProperty . SetValue ( throughInstance , entity . Id ) ;
247+ hasManyThrough . LeftProperty . SetValue ( throughInstance , entity ) ;
248+ hasManyThrough . RightProperty . SetValue ( throughInstance , pointer ) ;
249+
250+ var pointerId = ( pointer as Identifiable < TId > ) // known limitation, just need to come up with a solution...
251+ ?? throw new JsonApiException ( 500 , $ "Cannot update the HasManyThrough relationship '{ hasManyThrough . PublicRelationshipName } '. Id type must match the parent resource id type.") ;
252+
253+ hasManyThrough . RightIdProperty . SetValue ( throughInstance , pointerId . Id ) ;
254+
255+ throughRelationshipCollection . Add ( throughInstance ) ;
256+ }
257+ }
258+ }
259+ }
260+
229261 /// <summary>
230262 /// This is used to allow creation of HasOne relationships when the
231263 /// independent side of the relationship already exists.
@@ -252,7 +284,7 @@ public virtual async Task<TEntity> UpdateAsync(TId id, TEntity entity)
252284 foreach ( var relationship in _jsonApiContext . RelationshipsToUpdate )
253285 relationship . Key . SetValue ( oldEntity , relationship . Value ) ;
254286
255- AttachRelationships ( entity ) ;
287+ UpdateHasManyThrough ( entity ) ;
256288
257289 await _context . SaveChangesAsync ( ) ;
258290
0 commit comments