@@ -199,9 +199,7 @@ private void AttachHasManyPointers(TEntity entity)
199
199
private void AttachHasMany ( HasManyAttribute relationship , IList pointers )
200
200
{
201
201
foreach ( var pointer in pointers )
202
- {
203
202
_context . Entry ( pointer ) . State = EntityState . Unchanged ;
204
- }
205
203
}
206
204
207
205
private void AttachHasManyThrough ( TEntity entity , HasManyThroughAttribute hasManyThrough , IList pointers )
@@ -218,14 +216,48 @@ private void AttachHasManyThrough(TEntity entity, HasManyThroughAttribute hasMan
218
216
_context . Entry ( pointer ) . State = EntityState . Unchanged ;
219
217
220
218
var throughInstance = Activator . CreateInstance ( hasManyThrough . ThroughType ) ;
221
- _context . Entry ( throughInstance ) . State = EntityState . Added ;
222
-
223
219
hasManyThrough . LeftProperty . SetValue ( throughInstance , entity ) ;
224
220
hasManyThrough . RightProperty . SetValue ( throughInstance , pointer ) ;
221
+
225
222
throughRelationshipCollection . Add ( throughInstance ) ;
226
223
}
227
224
}
228
225
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
+
229
261
/// <summary>
230
262
/// This is used to allow creation of HasOne relationships when the
231
263
/// independent side of the relationship already exists.
@@ -252,7 +284,7 @@ public virtual async Task<TEntity> UpdateAsync(TId id, TEntity entity)
252
284
foreach ( var relationship in _jsonApiContext . RelationshipsToUpdate )
253
285
relationship . Key . SetValue ( oldEntity , relationship . Value ) ;
254
286
255
- AttachRelationships ( entity ) ;
287
+ UpdateHasManyThrough ( entity ) ;
256
288
257
289
await _context . SaveChangesAsync ( ) ;
258
290
0 commit comments