private static async Task <IReliableIndexedDictionary <TKey, TValue> > GetIndexedDictionaryByPropertyName <TKey, TValue, TFilter>(IReliableStateManager stateManager, string dictName, string propertyName) where TKey : IComparable <TKey>, IEquatable <TKey> where TFilter : IComparable <TFilter>, IEquatable <TFilter> { FilterableIndex <TKey, TValue, TFilter> filter = FilterableIndex <TKey, TValue, TFilter> .CreateQueryableInstance(propertyName); ConditionalValue <IReliableIndexedDictionary <TKey, TValue> > dictOption = await stateManager.TryGetIndexedAsync <TKey, TValue>(dictName, new[] { filter }); if (dictOption.HasValue) { return(dictOption.Value); } else { return(null); } }
public void TestInitialize() { userDictionaryManager = new MockReliableStateManager(); indexed_users = userDictionaryManager.GetOrAddIndexedAsync <UserName, Basic.Common.UserProfile>("indexed_users", FilterableIndex <UserName, Basic.Common.UserProfile, string> .CreateQueryableInstance("Email"), FilterableIndex <UserName, Basic.Common.UserProfile, int> .CreateQueryableInstance("Age")).Result; for (int i = 0; i < 5; i++) { using (var tx = userDictionaryManager.CreateTransaction()) { var user = new Basic.Common.UserProfile { Name = new UserName { First = $"First{i}", Last = $"Last{i}", }, Email = $"user-{i}@example.com", Age = 20 + i / 3, Address = new Basic.Common.Address { AddressLine1 = $"1{i} Main St.", City = "Seattle", State = "WA", Zipcode = 98117, }, }; indexed_users.SetAsync(tx, user.Name, user, TimeSpan.FromSeconds(4), new CancellationToken()); tx.CommitAsync(); } } Assert.IsTrue(userDictionaryManager.TryGetIndexedAsync <UserName, Basic.Common.UserProfile>("indexed_users", FilterableIndex <UserName, Basic.Common.UserProfile, string> .CreateQueryableInstance("Email"), FilterableIndex <UserName, Basic.Common.UserProfile, int> .CreateQueryableInstance("Age")).Result.HasValue); }
protected override async Task RunAsync(CancellationToken cancellationToken) { // Make a traditional IReliableDictionary <UserName, UserProfile> var users = await StateManager.GetOrAddAsync <IReliableDictionary <UserName, UserProfile> >("users"); // Make an IReliableIndexedDictionary <UserName, UserProfile>, with two indices: // Index<UserProfile.Email, UserName[]> and Index<UserProfile.Age, UserName[]> var indexed_users = await StateManager.GetOrAddIndexedAsync <UserName, UserProfile>("indexed_users", FilterableIndex <UserName, UserProfile, string> .CreateQueryableInstance("Email"), FilterableIndex <UserName, UserProfile, int> .CreateQueryableInstance("Age")); // The above dictionaries have the same content (below), but because the second has indices, // Linq queries and external queries should use that and be faster. for (int i = 0; i < 100; i++) { using (var tx = StateManager.CreateTransaction()) { var user = new UserProfile { Name = new UserName { First = $"First{i}", Last = $"Last{i}", }, Email = $"user-{i}@example.com", Age = 20 + i / 3, Address = new Address { AddressLine1 = $"1{i} Main St.", City = "Seattle", State = "WA", Zipcode = 98117, }, }; await users.SetAsync(tx, user.Name, user, TimeSpan.FromSeconds(4), cancellationToken); await indexed_users.SetAsync(tx, user.Name, user, TimeSpan.FromSeconds(4), cancellationToken); await tx.CommitAsync(); } } /* Example of LINQ querying on IReliableIndexedDictionary * * Sometimes you will want your application code to carry out queries against your RC as well, and LINQ is a great way to do so * * Also, when you write your query, make sure to put all your WHERE logic into a single WHERE statement * since each statement carries its own context the indexing middleware cannot efficiently operate on disjoint statements, * e.g. use qdict.Where(x => x.Email == "*****@*****.**" && x.Age <= 20) instead of * qdict.Where(x => x.Email == "*****@*****.**").Where(x => x.Age <= 20) */ // Create LINQ-Queryable state of IndexedDictionary var qdict = new QueryableReliableIndexedDictionary <UserName, UserProfile, UserProfile>(indexed_users, StateManager); // Create the same query two different ways var query = from UserProfile profile in qdict where profile.Age >= 20 && profile.Email == "*****@*****.**" && profile.Age <= 20 select profile; var query2 = qdict.Where(x => x.Email == "*****@*****.**" && x.Age <= 20); // Execute the queries, add breakpoints here to see results foreach (UserProfile profile in query) { } foreach (UserProfile profile in query2) { } }