@@ -155,24 +155,46 @@ public virtual async Task<TEntity> CreateAsync(TEntity entity)
155155 protected virtual void AttachRelationships ( TEntity entity = null )
156156 {
157157 AttachHasManyPointers ( entity ) ;
158- AttachHasOnePointers ( ) ;
158+ AttachHasOnePointers ( entity ) ;
159159 }
160160
161161 /// <inheritdoc />
162162 public void DetachRelationshipPointers ( TEntity entity )
163163 {
164164 foreach ( var hasOneRelationship in _jsonApiContext . HasOneRelationshipPointers . Get ( ) )
165165 {
166- _context . Entry ( hasOneRelationship . Value ) . State = EntityState . Detached ;
166+ var hasOne = ( HasOneAttribute ) hasOneRelationship . Key ;
167+ if ( hasOne . EntityPropertyName != null )
168+ {
169+ var relatedEntity = entity . GetType ( ) . GetProperty ( hasOne . EntityPropertyName ) ? . GetValue ( entity ) ;
170+ if ( relatedEntity != null )
171+ _context . Entry ( relatedEntity ) . State = EntityState . Detached ;
172+ }
173+ else
174+ {
175+ _context . Entry ( hasOneRelationship . Value ) . State = EntityState . Detached ;
176+ }
167177 }
168178
169179 foreach ( var hasManyRelationship in _jsonApiContext . HasManyRelationshipPointers . Get ( ) )
170180 {
171- foreach ( var pointer in hasManyRelationship . Value )
181+ var hasMany = ( HasManyAttribute ) hasManyRelationship . Key ;
182+ if ( hasMany . EntityPropertyName != null )
172183 {
173- _context . Entry ( pointer ) . State = EntityState . Detached ;
184+ var relatedList = ( IList ) entity . GetType ( ) . GetProperty ( hasMany . EntityPropertyName ) ? . GetValue ( entity ) ;
185+ foreach ( var related in relatedList )
186+ {
187+ _context . Entry ( related ) . State = EntityState . Detached ;
188+ }
174189 }
175-
190+ else
191+ {
192+ foreach ( var pointer in hasManyRelationship . Value )
193+ {
194+ _context . Entry ( pointer ) . State = EntityState . Detached ;
195+ }
196+ }
197+
176198 // HACK: detaching has many relationships doesn't appear to be sufficient
177199 // the navigation property actually needs to be nulled out, otherwise
178200 // EF adds duplicate instances to the collection
@@ -192,14 +214,27 @@ private void AttachHasManyPointers(TEntity entity)
192214 if ( relationship . Key is HasManyThroughAttribute hasManyThrough )
193215 AttachHasManyThrough ( entity , hasManyThrough , relationship . Value ) ;
194216 else
195- AttachHasMany ( relationship . Key as HasManyAttribute , relationship . Value ) ;
217+ AttachHasMany ( entity , relationship . Key as HasManyAttribute , relationship . Value ) ;
196218 }
197219 }
198220
199- private void AttachHasMany ( HasManyAttribute relationship , IList pointers )
221+ private void AttachHasMany ( TEntity entity , HasManyAttribute relationship , IList pointers )
200222 {
201- foreach ( var pointer in pointers )
202- _context . Entry ( pointer ) . State = EntityState . Unchanged ;
223+ if ( relationship . EntityPropertyName != null )
224+ {
225+ var relatedList = ( IList ) entity . GetType ( ) . GetProperty ( relationship . EntityPropertyName ) ? . GetValue ( entity ) ;
226+ foreach ( var related in relatedList )
227+ {
228+ _context . Entry ( related ) . State = EntityState . Unchanged ;
229+ }
230+ }
231+ else
232+ {
233+ foreach ( var pointer in pointers )
234+ {
235+ _context . Entry ( pointer ) . State = EntityState . Unchanged ;
236+ }
237+ }
203238 }
204239
205240 private void AttachHasManyThrough ( TEntity entity , HasManyThroughAttribute hasManyThrough , IList pointers )
@@ -227,12 +262,27 @@ private void AttachHasManyThrough(TEntity entity, HasManyThroughAttribute hasMan
227262 /// This is used to allow creation of HasOne relationships when the
228263 /// independent side of the relationship already exists.
229264 /// </summary>
230- private void AttachHasOnePointers ( )
265+ private void AttachHasOnePointers ( TEntity entity )
231266 {
232267 var relationships = _jsonApiContext . HasOneRelationshipPointers . Get ( ) ;
233268 foreach ( var relationship in relationships )
234- if ( _context . Entry ( relationship . Value ) . State == EntityState . Detached && _context . EntityIsTracked ( relationship . Value ) == false )
235- _context . Entry ( relationship . Value ) . State = EntityState . Unchanged ;
269+ {
270+ if ( relationship . Key . GetType ( ) != typeof ( HasOneAttribute ) )
271+ continue ;
272+
273+ var hasOne = ( HasOneAttribute ) relationship . Key ;
274+ if ( hasOne . EntityPropertyName != null )
275+ {
276+ var relatedEntity = entity . GetType ( ) . GetProperty ( hasOne . EntityPropertyName ) ? . GetValue ( entity ) ;
277+ if ( relatedEntity != null && _context . Entry ( relatedEntity ) . State == EntityState . Detached && _context . EntityIsTracked ( ( IIdentifiable ) relatedEntity ) == false )
278+ _context . Entry ( relatedEntity ) . State = EntityState . Unchanged ;
279+ }
280+ else
281+ {
282+ if ( _context . Entry ( relationship . Value ) . State == EntityState . Detached && _context . EntityIsTracked ( relationship . Value ) == false )
283+ _context . Entry ( relationship . Value ) . State = EntityState . Unchanged ;
284+ }
285+ }
236286 }
237287
238288 /// <inheritdoc />
0 commit comments