Created
April 13, 2015 18:09
-
-
Save josheinstein/f405b293bc4bb1149f49 to your computer and use it in GitHub Desktop.
LINQPad example of using StartsWith on RowKey and PartitionKey properties in Windows Azure Table Storage.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void Main() | |
{ | |
// Windows Azure Table Storage does not support a StartsWith function | |
// on string properties. However, it does support the CompareTo function. | |
// This will allow us to simulate the StartsWith function by taking the | |
// substring that you want to match on and figuring out the exclusive | |
// upper bound by incrementing the last character. | |
// In this example, Buildings is a table that uses a postal code as | |
// the partition key. The results would include the zip codes: | |
// 19380, 19381, ... up through 19389. | |
// This becomes: | |
// (RowKey ge '1938') and (RowKey lt '1939') | |
Buildings | |
.WherePartitionKeyStartsWith("1938") | |
.Take(100) | |
.Dump(); | |
} | |
public static class AzureTableExtensions { | |
// Applies a predicate to the queryable that limits results to entities | |
// that have a row key that begins with the specified substring. | |
public static IQueryable<T> WhereRowKeyStartsWith<T>(this IQueryable<T> query, string startsWith) where T : ITableEntity { | |
string upperBound = CreateUpperBoundString(startsWith); | |
return query.Where( x => | |
x.RowKey.CompareTo(startsWith) >= 0 && | |
x.RowKey.CompareTo(upperBound) < 0 | |
); | |
} | |
// Applies a predicate to the queryable that limits results to entities | |
// that have a partition key that begins with the specified substring. | |
public static IQueryable<T> WherePartitionKeyStartsWith<T>(this IQueryable<T> query, string startsWith) where T : ITableEntity, new() { | |
string upperBound = CreateUpperBoundString(startsWith); | |
return query.Where( x => | |
x.PartitionKey.CompareTo(startsWith) >= 0 && | |
x.PartitionKey.CompareTo(upperBound) < 0 | |
); | |
} | |
// Given a string, returns a string that can be used as an upper bound in | |
// a range query to achieve the same functionality as a StartsWith operator. | |
// For example, passing ABCD as the lower bound will return ABCE as the upper | |
// bound, so that the range would contain ABCD, ABCD0000, ABCDE, and everything | |
// up until ABCE, which is the exclusive upper bound. | |
private static string CreateUpperBoundString(string lowerBoundString) { | |
if (String.IsNullOrEmpty(lowerBoundString)) { | |
throw new ArgumentException("lowerBoundString parameter cannot be a null or empty string.", "lowerBoundString"); | |
} | |
// increment the last character of the inclusive lower bound | |
// to get the exclusive upper bound. | |
string upperBoundString = lowerBoundString.Substring(0,lowerBoundString.Length-1) + | |
(char)(lowerBoundString[lowerBoundString.Length-1] + 1); | |
return upperBoundString; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment