Here’s a small gotcha that I didn’t see covered via the normal Google coverage. So, I’m adding the information and the solution so that I can find the answer when I need it again. I’m sharing via my blog to help you out too. If this helps you, click on a link and send some change my way:)
Symptom: You follow the rules and ran “Create Test Storage Tables” from Visual Studio on your dev box. All your testing locally seems to work. When you deploy, you see an error like this (leaving in lots of Google discovery goodness in here. If this saves your bacon, send me a thank you!):
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<code>TableNotFound</code>
<message xml:lang="en-US">The table specified does not exist.</message>
</error>
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Data.Services.Client.DataServiceClientException: <?xml version="1.0" encoding="utf-8" standalone="yes"?>
<error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<code>TableNotFound</code>
<message xml:lang="en-US">The table specified does not exist.</message>
</error>
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[DataServiceClientException: <?xml version="1.0" encoding="utf-8" standalone="yes"?> <error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"> <code>TableNotFound</code> <message xml:lang="en-US">The table specified does not exist.</message> </error> ] System.Data.Services.Client.<HandleBatchResponse>d__1d.MoveNext() +1294 [DataServiceRequestException: An error occurred while processing this request.] System.Data.Services.Client.SaveAsyncResult.HandleBatchResponse() +391100 System.Data.Services.Client.DataServiceContext.SaveChanges(SaveChangesOptions options) +177 Microsoft.Samples.ServiceHosting.StorageClient.<>c__DisplayClass1.<SaveChangesWithRetries>b__0() in C:UsersScott SeelyDocumentsVisual Studio 2008ProjectsAzureSamplesStorageClientLibTableStorage.cs:1227 Microsoft.Samples.ServiceHosting.StorageClient.RetryPolicies.NoRetry(Action action) in C:UsersScott SeelyDocumentsVisual Studio 2008ProjectsAzureSamplesStorageClientLibBlobStorage.cs:220 Microsoft.Samples.ServiceHosting.StorageClient.TableStorageDataServiceContext.SaveChangesWithRetries() in C:UsersScott SeelyDocumentsVisual Studio 2008ProjectsAzureSamplesStorageClientLibTableStorage.cs:1215
The critical part to fixing this was to make sure that my tables were actually initialized prior to running any queries. The class that holds my IQueryable so that the table storage actually works now has an Init() function. The class itself now reads:
public class AzureMembershipDataContext : TableStorageDataServiceContext
{
public AzureMembershipDataContext() :
base(StorageAccountInfo.GetDefaultTableStorageAccountFromConfiguration())
{
Init();
}
private const string TableName = "AzureUserTable";
public IQueryable<AzureUserData> AzureUserTable
{
get
{
return CreateQuery<AzureUserData>(TableName);
}
}
private static bool _initalized = false;
static void Init()
{
if (!_initalized)
{
StorageAccountInfo storageAccountInfo =
StorageAccountInfo.GetDefaultTableStorageAccountFromConfiguration();
TableStorage.CreateTablesFromModel(typeof(AzureMembershipDataContext), storageAccountInfo);
_initalized = true;
}
}
public void Add(AzureUserData data)
{
base.AddObject(TableName, data);
}
}
And yeah-that code to actually CreateTablesFromModel in Init() is super important. Without it, you can’t do anything. Make sure the model is created from the type containing your IQueryable-going off of the table type doesn’t work with the API.