@@ -85,7 +85,7 @@ public virtual async Task<TEntity> GetAndIncludeAsync(TId id, string relationshi
8585 {
8686 _logger . LogDebug ( $ "[JADN] GetAndIncludeAsync({ id } , { relationshipName } )") ;
8787
88- var includedSet = await IncludeAsync ( Get ( ) , relationshipName ) ;
88+ var includedSet = Include ( Get ( ) , relationshipName ) ;
8989 var result = await includedSet . SingleOrDefaultAsync ( e => e . Id . Equals ( id ) ) ;
9090
9191 return result ;
@@ -108,6 +108,28 @@ protected virtual void AttachRelationships()
108108 AttachHasOnePointers ( ) ;
109109 }
110110
111+ /// <inheritdoc />
112+ public void DetachRelationshipPointers ( TEntity entity )
113+ {
114+ foreach ( var hasOneRelationship in _jsonApiContext . HasOneRelationshipPointers . Get ( ) )
115+ {
116+ _context . Entry ( hasOneRelationship . Value ) . State = EntityState . Detached ;
117+ }
118+
119+ foreach ( var hasManyRelationship in _jsonApiContext . HasManyRelationshipPointers . Get ( ) )
120+ {
121+ foreach ( var pointer in hasManyRelationship . Value )
122+ {
123+ _context . Entry ( pointer ) . State = EntityState . Detached ;
124+ }
125+
126+ // HACK: detaching has many relationships doesn't appear to be sufficient
127+ // the navigation property actually needs to be nulled out, otherwise
128+ // EF adds duplicate instances to the collection
129+ hasManyRelationship . Key . SetValue ( entity , null ) ;
130+ }
131+ }
132+
111133 /// <summary>
112134 /// This is used to allow creation of HasMany relationships when the
113135 /// dependent side of the relationship already exists.
@@ -178,7 +200,6 @@ public virtual async Task<bool> DeleteAsync(TId id)
178200 }
179201
180202 /// <inheritdoc />
181- [ Obsolete ( "Use IncludeAsync" ) ]
182203 public virtual IQueryable < TEntity > Include ( IQueryable < TEntity > entities , string relationshipName )
183204 {
184205 var entity = _jsonApiContext . RequestEntity ;
@@ -197,52 +218,6 @@ public virtual IQueryable<TEntity> Include(IQueryable<TEntity> entities, string
197218 return entities . Include ( relationship . InternalRelationshipName ) ;
198219 }
199220
200- /// <inheritdoc />
201- public virtual async Task < IQueryable < TEntity > > IncludeAsync ( IQueryable < TEntity > entities , string relationshipName )
202- {
203- var entity = _jsonApiContext . RequestEntity ;
204- var relationship = entity . Relationships . FirstOrDefault ( r => r . PublicRelationshipName == relationshipName ) ;
205- if ( relationship == null )
206- {
207- throw new JsonApiException ( 400 , $ "Invalid relationship { relationshipName } on { entity . EntityName } ",
208- $ "{ entity . EntityName } does not have a relationship named { relationshipName } ") ;
209- }
210-
211- if ( ! relationship . CanInclude )
212- {
213- throw new JsonApiException ( 400 , $ "Including the relationship { relationshipName } on { entity . EntityName } is not allowed") ;
214- }
215-
216- await ReloadPointerAsync ( relationship ) ;
217-
218- return entities . Include ( relationship . InternalRelationshipName ) ;
219- }
220-
221- /// <summary>
222- /// Ensure relationships on the provided entity have been fully loaded from the database.
223- /// </summary>
224- /// <remarks>
225- /// The only known case when this should be called is when a POST request is
226- /// sent with an ?include query.
227- ///
228- /// See https://github.com/json-api-dotnet/JsonApiDotNetCore/issues/343
229- /// </remarks>
230- private async Task ReloadPointerAsync ( RelationshipAttribute relationshipAttr )
231- {
232- if ( relationshipAttr . IsHasOne && _jsonApiContext . HasOneRelationshipPointers . Get ( ) . TryGetValue ( relationshipAttr , out var pointer ) )
233- {
234- await _context . Entry ( pointer ) . ReloadAsync ( ) ;
235- }
236-
237- if ( relationshipAttr . IsHasMany && _jsonApiContext . HasManyRelationshipPointers . Get ( ) . TryGetValue ( relationshipAttr , out var pointers ) )
238- {
239- foreach ( var hasManyPointer in pointers )
240- {
241- await _context . Entry ( hasManyPointer ) . ReloadAsync ( ) ;
242- }
243- }
244- }
245-
246221 /// <inheritdoc />
247222 public virtual async Task < IEnumerable < TEntity > > PageAsync ( IQueryable < TEntity > entities , int pageSize , int pageNumber )
248223 {
0 commit comments