/// <inheritdoc /> public async Task MoveAsync(DbRef newLocation, ICacheClient redis, CancellationToken cancellationToken) { if (redis == null) { throw new ArgumentNullException(nameof(redis)); } Debug.Assert(!newLocation.Equals(DbRef.Nothing), "!newLocation.Equals(DbRef.NOTHING)"); Debug.Assert(!newLocation.Equals(DbRef.Ambiguous), "!newLocation.Equals(DbRef.AMBIGUOUS)"); Debug.Assert(!newLocation.Equals(DbRef.FailedMatch), "!newLocation.Equals(DbRef.FAILED_MATCH)"); if (redis == null) { throw new ArgumentNullException(nameof(redis)); } if (this.Location.Equals(newLocation)) { return; } var oldLocationObject = this.Location.Equals(DbRef.Nothing) ? null : await CacheManager.LookupOrRetrieveAsync(this.Location, redis, async (d, token) => await GetAsync(redis, d, token), cancellationToken); var newLocationObject = await CacheManager.LookupOrRetrieveAsync(newLocation, redis, async (d, token) => await GetAsync(redis, d, token), cancellationToken); if (newLocationObject != null) { if (oldLocationObject != null) { oldLocationObject.DataObject.RemoveContents(this.DbRef); await oldLocationObject.DataObject.SaveAsync(redis, cancellationToken); } newLocationObject.DataObject.AddContents(this.DbRef); await newLocationObject.DataObject.SaveAsync(redis, cancellationToken); this.Location = newLocation; await this.SaveAsync(redis, cancellationToken); var genericUpdateAsync = typeof(CacheManager).GetMethod(nameof(CacheManager.UpdateAsync)).MakeGenericMethod(newLocationObject.DataObject.GetType()); var task = (Task)genericUpdateAsync.Invoke(null, new object[] { newLocation, redis, newLocationObject.DataObject, cancellationToken }); Debug.Assert(task != null, "task != null"); await task; } }