/// <summary> /// Begins the async load operation /// </summary> /// <param name="id">The id.</param> /// <param name="token">The canecllation token.</param> /// <returns></returns> public async Task <T> LoadAsync <T>(string id, CancellationToken token = default(CancellationToken)) { if (id == null) { throw new ArgumentNullException("id", "The document id cannot be null"); } object entity; if (EntitiesById.TryGetValue(id, out entity)) { return((T)entity); } JsonDocument value; if (includedDocumentsByKey.TryGetValue(id, out value)) { includedDocumentsByKey.Remove(id); return(TrackEntity <T>(value)); } if (IsDeleted(id)) { return(default(T)); } IncrementRequestCount(); var loadOperation = new LoadOperation(this, AsyncDatabaseCommands.DisableAllCaching, id); return(await CompleteLoadAsync <T>(id, loadOperation, token).ConfigureAwait(false)); }
/// <summary> /// Return the entity by it's id /// </summary> /// <param name="entityId"></param> /// <returns></returns> public DirectEntity GetEntityById(long entityId) { DirectEntity entity; if (EntitiesById.TryGetValue(entityId, out entity)) { return(entity); } return(null); }
public T Load <T>(string id) { object existingEntity; if (EntitiesById.TryGetValue(id, out existingEntity)) { return((T)existingEntity); } IncrementRequestCount(); var shardRequestData = new ShardRequestData { EntityType = typeof(T), Keys = { id } }; var dbCommands = GetCommandsToOperateOn(shardRequestData); var results = shardStrategy.ShardAccessStrategy.Apply(dbCommands, shardRequestData, (commands, i) => { var loadOperation = new LoadOperation(this, commands.DisableAllCaching, id); bool retry; do { loadOperation.LogOperation(); using (loadOperation.EnterLoadContext()) { retry = loadOperation.SetResult(commands.Get(id)); } } while (retry); return(loadOperation.Complete <T>().FirstOrDefault()); }); var shardsContainThisDocument = results.Where(x => !Equals(x, default(T))).ToArray(); if (shardsContainThisDocument.Length > 1) { throw new InvalidOperationException("Found document with id: " + id + " on more than a single shard, which is not allowed. Document keys have to be unique cluster-wide."); } return(shardsContainThisDocument.FirstOrDefault()); }
/// <summary> /// Loads the specified entity with the specified id. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="id">The id.</param> /// <returns></returns> public T Load <T>(string id) { if (id == null) { throw new ArgumentNullException("id", "The document id cannot be null"); } if (IsDeleted(id)) { return(default(T)); } object existingEntity; if (EntitiesById.TryGetValue(id, out existingEntity)) { return((T)existingEntity); } JsonDocument value; if (includedDocumentsByKey.TryGetValue(id, out value)) { includedDocumentsByKey.Remove(id); return(TrackEntity <T>(value)); } IncrementRequestCount(); var loadOperation = new LoadOperation(this, DatabaseCommands.DisableAllCaching, id); bool retry; do { loadOperation.LogOperation(); using (loadOperation.EnterLoadContext()) { retry = loadOperation.SetResult(DatabaseCommands.Get(id)); } } while (retry); return(loadOperation.Complete <T>().FirstOrDefault()); }
public T[] LoadInternal <T>(string[] ids, KeyValuePair <string, Type>[] includes) { var results = new T[ids.Length]; var includePaths = includes != null?includes.Select(x => x.Key).ToArray() : null; var idsToLoad = GetIdsThatNeedLoading <T>(ids, includePaths, transformer: null); if (!idsToLoad.Any()) { return(results); } IncrementRequestCount(); foreach (var shard in idsToLoad) { var currentShardIds = shard.Select(x => x.Id).ToArray(); var multiLoadOperations = shardStrategy.ShardAccessStrategy.Apply(shard.Key, new ShardRequestData { EntityType = typeof(T), Keys = currentShardIds.ToList() }, (dbCmd, i) => { var multiLoadOperation = new LoadOperation(this, dbCmd.DisableAllCaching, currentShardIds, includes); LoadResult loadResult; do { multiLoadOperation.LogOperation(); using (multiLoadOperation.EnterLoadContext()) { loadResult = dbCmd.Get(currentShardIds, includePaths); } } while (multiLoadOperation.SetResult(loadResult)); return(multiLoadOperation); }); foreach (var multiLoadOperation in multiLoadOperations) { var loadResults = multiLoadOperation.Complete <T>(); for (int i = 0; i < loadResults.Length; i++) { if (ReferenceEquals(loadResults[i], null)) { continue; } var id = currentShardIds[i]; var itemPosition = Array.IndexOf(ids, id); if (ReferenceEquals(results[itemPosition], default(T)) == false) { throw new InvalidOperationException("Found document with id: " + id + " on more than a single shard, which is not allowed. Document keys have to be unique cluster-wide."); } results[itemPosition] = loadResults[i]; } } } return(ids.Select(id => // so we get items that were skipped because they are already in the session cache { object val; EntitiesById.TryGetValue(id, out val); return (T)val; }).ToArray()); }
public Task <T> LoadAsync <T>(string id, CancellationToken token = default(CancellationToken)) { if (KnownMissingIds.Contains(id)) { return(CompletedTask.With(default(T))); } object existingEntity; if (EntitiesById.TryGetValue(id, out existingEntity)) { return(CompletedTask.With((T)existingEntity)); } IncrementRequestCount(); var shardRequestData = new ShardRequestData { EntityType = typeof(T), Keys = { id } }; var dbCommands = GetCommandsToOperateOn(shardRequestData); var results = shardStrategy.ShardAccessStrategy.ApplyAsync(dbCommands, shardRequestData, (commands, i) => { var loadOperation = new LoadOperation(this, commands.DisableAllCaching, id); Func <Task> executer = null; executer = () => { loadOperation.LogOperation(); var loadContext = loadOperation.EnterLoadContext(); return(commands.GetAsync(id, token: token).ContinueWith(task => { if (loadContext != null) { loadContext.Dispose(); } if (loadOperation.SetResult(task.Result)) { return executer(); } return new CompletedTask(); }).Unwrap()); }; return(executer().ContinueWith(_ => { _.AssertNotFailed(); return loadOperation.Complete <T>(); }).WithCancellation(token)); }); return(results.ContinueWith(task => { var shardsContainThisDocument = task.Result.Select(arg => arg.FirstOrDefault()).Where(x => !Equals(x, default(T))).ToArray(); if (shardsContainThisDocument.Count() > 1) { throw new InvalidOperationException("Found document with id: " + id + " on more than a single shard, which is not allowed. Document keys have to be unique cluster-wide."); } return shardsContainThisDocument.FirstOrDefault(); }).WithCancellation(token)); }