@@ -85,7 +85,7 @@ public virtual async Task<TEntity> GetAndIncludeAsync(TId id, string relationshi
85
85
{
86
86
_logger . LogDebug ( $ "[JADN] GetAndIncludeAsync({ id } , { relationshipName } )") ;
87
87
88
- var includedSet = await IncludeAsync ( Get ( ) , relationshipName ) ;
88
+ var includedSet = Include ( Get ( ) , relationshipName ) ;
89
89
var result = await includedSet . SingleOrDefaultAsync ( e => e . Id . Equals ( id ) ) ;
90
90
91
91
return result ;
@@ -108,6 +108,28 @@ protected virtual void AttachRelationships()
108
108
AttachHasOnePointers ( ) ;
109
109
}
110
110
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
+
111
133
/// <summary>
112
134
/// This is used to allow creation of HasMany relationships when the
113
135
/// dependent side of the relationship already exists.
@@ -178,7 +200,6 @@ public virtual async Task<bool> DeleteAsync(TId id)
178
200
}
179
201
180
202
/// <inheritdoc />
181
- [ Obsolete ( "Use IncludeAsync" ) ]
182
203
public virtual IQueryable < TEntity > Include ( IQueryable < TEntity > entities , string relationshipName )
183
204
{
184
205
var entity = _jsonApiContext . RequestEntity ;
@@ -197,52 +218,6 @@ public virtual IQueryable<TEntity> Include(IQueryable<TEntity> entities, string
197
218
return entities . Include ( relationship . InternalRelationshipName ) ;
198
219
}
199
220
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
-
246
221
/// <inheritdoc />
247
222
public virtual async Task < IEnumerable < TEntity > > PageAsync ( IQueryable < TEntity > entities , int pageSize , int pageNumber )
248
223
{
0 commit comments