@@ -155,24 +155,46 @@ public virtual async Task<TEntity> CreateAsync(TEntity entity)
155
155
protected virtual void AttachRelationships ( TEntity entity = null )
156
156
{
157
157
AttachHasManyPointers ( entity ) ;
158
- AttachHasOnePointers ( ) ;
158
+ AttachHasOnePointers ( entity ) ;
159
159
}
160
160
161
161
/// <inheritdoc />
162
162
public void DetachRelationshipPointers ( TEntity entity )
163
163
{
164
164
foreach ( var hasOneRelationship in _jsonApiContext . HasOneRelationshipPointers . Get ( ) )
165
165
{
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
+ }
167
177
}
168
178
169
179
foreach ( var hasManyRelationship in _jsonApiContext . HasManyRelationshipPointers . Get ( ) )
170
180
{
171
- foreach ( var pointer in hasManyRelationship . Value )
181
+ var hasMany = ( HasManyAttribute ) hasManyRelationship . Key ;
182
+ if ( hasMany . EntityPropertyName != null )
172
183
{
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
+ }
174
189
}
175
-
190
+ else
191
+ {
192
+ foreach ( var pointer in hasManyRelationship . Value )
193
+ {
194
+ _context . Entry ( pointer ) . State = EntityState . Detached ;
195
+ }
196
+ }
197
+
176
198
// HACK: detaching has many relationships doesn't appear to be sufficient
177
199
// the navigation property actually needs to be nulled out, otherwise
178
200
// EF adds duplicate instances to the collection
@@ -192,14 +214,27 @@ private void AttachHasManyPointers(TEntity entity)
192
214
if ( relationship . Key is HasManyThroughAttribute hasManyThrough )
193
215
AttachHasManyThrough ( entity , hasManyThrough , relationship . Value ) ;
194
216
else
195
- AttachHasMany ( relationship . Key as HasManyAttribute , relationship . Value ) ;
217
+ AttachHasMany ( entity , relationship . Key as HasManyAttribute , relationship . Value ) ;
196
218
}
197
219
}
198
220
199
- private void AttachHasMany ( HasManyAttribute relationship , IList pointers )
221
+ private void AttachHasMany ( TEntity entity , HasManyAttribute relationship , IList pointers )
200
222
{
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
+ }
203
238
}
204
239
205
240
private void AttachHasManyThrough ( TEntity entity , HasManyThroughAttribute hasManyThrough , IList pointers )
@@ -227,12 +262,27 @@ private void AttachHasManyThrough(TEntity entity, HasManyThroughAttribute hasMan
227
262
/// This is used to allow creation of HasOne relationships when the
228
263
/// independent side of the relationship already exists.
229
264
/// </summary>
230
- private void AttachHasOnePointers ( )
265
+ private void AttachHasOnePointers ( TEntity entity )
231
266
{
232
267
var relationships = _jsonApiContext . HasOneRelationshipPointers . Get ( ) ;
233
268
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
+ }
236
286
}
237
287
238
288
/// <inheritdoc />
0 commit comments