1.Create a table)
#region New Table public void NewTable(string tableName) { if (CloudStorageAccount == null) return; try { ClearStatus(); CloudTableClient tableClient = CloudStorageAccount.CreateCloudTableClient(); tableClient.CreateTable(tableName); Refresh(); ReportSuccess("Table " + tableName + " created."); } catch (Exception ex) { ReportException(ex); } } #endregion
2.Copy a table)
#region Copy Table public void CopyTable(string name, string destName) { DetailSpinnerVisible = Visibility.Visible; SourceTableName = name; DestTableName = destName; ReportActive("Copying table " + name + " to " + destName + "..."); UploadInProgress = true; BackgroundWorker background = new BackgroundWorker(); background.DoWork += new DoWorkEventHandler(Background_CopyEntities); background.RunWorkerCompleted += new RunWorkerCompletedEventHandler(Background_CopyEntitiesCompleted); background.RunWorkerAsync(); } private void Background_CopyEntities(object sender, DoWorkEventArgs e) { List<GenericEntity> entityList = new List<GenericEntity>(); if (!OpenAccount()) return; try { CloudTableClient tableClient = CloudStorageAccount.CreateCloudTableClient(); tableClient.CreateTableIfNotExist(DestTableName); TableServiceContext tableServiceContext = CreateTableServiceContext(tableClient); CloudTableQuery<GenericEntity> cloudTableQuery = null; if (!String.IsNullOrEmpty(TableQuery)) { cloudTableQuery = (from entity in tableServiceContext.CreateQuery<GenericEntity>(SourceTableName) .AddQueryOption("$filter", TableQuery) select entity).AsTableServiceQuery<GenericEntity>(); } else { cloudTableQuery = (from entity in tableServiceContext.CreateQuery<GenericEntity>(SourceTableName) select entity).AsTableServiceQuery<GenericEntity>(); } IEnumerable<GenericEntity> entities = cloudTableQuery.Execute() as IEnumerable<GenericEntity>; // Read entities from source table and add to destination table. entityList.Clear(); foreach (GenericEntity entity in entities) { entityList.Add(entity); } tableClient = CloudStorageAccount.CreateCloudTableClient(); tableServiceContext = CreateTableServiceContext(tableClient); const int batchSize = 10; int batchRecords = 0; int entitiesCopiedCount = 0; foreach (GenericEntity entity in entityList) { tableServiceContext.AddObject(DestTableName, new GenericEntity(entity)); entitiesCopiedCount++; batchRecords++; if (batchRecords >= batchSize) { tableServiceContext.SaveChanges(SaveChangesOptions.Batch); batchRecords = 0; } } if (batchRecords > 0) { tableServiceContext.SaveChanges(SaveChangesOptions.Batch); } ReportSuccess("Table copy complete (" + DestTableName + ", " + entitiesCopiedCount.ToString() + " entities)"); } catch (Exception ex) { ReportException(ex); } } void Background_CopyEntitiesCompleted(object sender, RunWorkerCompletedEventArgs e) { UploadInProgress = false; DetailSpinnerVisible = Visibility.Collapsed; Refresh(); } #endregion
3.Rename a table)
#region Rename Table public void RenameTable(string name, string destName) { CloudTableClient tableClient = CloudStorageAccount.CreateCloudTableClient(); if (tableClient.DoesTableExist(destName)) { ReportError("Cannot rename table - the destination table '" + destName + "' already exists"); ListSpinnerVisible = Visibility.Collapsed; return; } DetailSpinnerVisible = Visibility.Visible; SourceTableName = name; DestTableName = destName; ReportActive("Copying table " + name + " to " + destName + "..."); UploadInProgress = true; BackgroundWorker background = new BackgroundWorker(); background.DoWork += new DoWorkEventHandler(Background_CopyEntities); background.RunWorkerCompleted += new RunWorkerCompletedEventHandler(Background_CopyEntitiesCompleted); background.RunWorkerAsync(); } #endregion
4. delete a table)
#region Delete Table public void DeleteTable(string tableName) { if (CloudStorageAccount == null) return; try { ClearStatus(); CloudTableClient tableClient = CloudStorageAccount.CreateCloudTableClient(); tableClient.DeleteTable(tableName); Refresh(); ReportSuccess("Table " + tableName + " deleted."); } catch (Exception ex) { ReportException(ex); } } #endregion
5.Create an entity and insert it to the table
public void NewEntity(string tableName, GenericEntity entity) { if (CloudStorageAccount == null) return; try { ClearStatus(); CloudTableClient tableClient = CloudStorageAccount.CreateCloudTableClient(); TableServiceContext tableServiceContext = CreateTableServiceContext(tableClient); tableServiceContext.AddObject(tableName, entity); tableServiceContext.SaveChanges(); RefreshDetail(tableName); ReportSuccess("New entity added to table"); } catch (Exception ex) { ReportException(ex); } }
6.Update the entity in a table)
public void UpdateEntity(string tableName, GenericEntity originalEntity, GenericEntity updatedEntity) { if (CloudStorageAccount == null) return; try { bool keyChanged = true; if (originalEntity.PartitionKey == updatedEntity.PartitionKey && originalEntity.RowKey == updatedEntity.RowKey) { keyChanged = false; } ClearStatus(); CloudTableClient tableClient = CloudStorageAccount.CreateCloudTableClient(); TableServiceContext tableServiceContext = CreateTableServiceContext(tableClient); IQueryable<GenericEntity> entities = (from entity in tableServiceContext.CreateQuery<GenericEntity>(tableName) where entity.PartitionKey == originalEntity.PartitionKey && entity.RowKey == originalEntity.RowKey select entity); List<GenericEntity> entitiesList = entities.ToList<GenericEntity>(); if (entitiesList != null && entitiesList.Count() > 0) { GenericEntity readEntity = entitiesList[0]; if (keyChanged) { // Key change, so add the new then delete the old. tableServiceContext.AddObject(tableName, updatedEntity); tableServiceContext.DeleteObject(readEntity); tableServiceContext.SaveChanges(); ReportSuccess("Entity " + originalEntity.Key() + " updated, new key " + updatedEntity.Key()); } else { // Key unchanged, so just update the entity. readEntity.Properties = updatedEntity.Properties; tableServiceContext.UpdateObject(readEntity); tableServiceContext.SaveChanges(SaveChangesOptions.ReplaceOnUpdate); ReportSuccess("Entity " + originalEntity.Key() + " updated, key unchanged"); } RefreshDetail(tableName); } else { ReportWarning("Entity " + originalEntity.Key() + " was not found"); } } catch (Exception ex) { ReportException(ex); } }
7.Delete An entity from a table)
{ try { DetailSpinnerVisible = Visibility.Visible; ClearStatus(); CloudTableClient tableClient = CloudStorageAccount.CreateCloudTableClient(); TableServiceContext tableServiceContext = CreateTableServiceContext(tableClient); IQueryable<GenericEntity> entities = (from entity in tableServiceContext.CreateQuery<GenericEntity>(tableName) where entity.PartitionKey == targetEntity.PartitionKey && entity.RowKey == targetEntity.RowKey select entity); GenericEntity entityToDelete = entities.FirstOrDefault(); if (entityToDelete != null) { tableServiceContext.DeleteObject(entityToDelete); tableServiceContext.SaveChanges(); } ReportSuccess("Entity " + targetEntity.Key() + " deleted"); return true; } catch (Exception ex) { ReportException(ex); RefreshDetail(tableName); return false; } } public void ReportDeleteEntities(string tableName, int deleted, int errors) { if (errors == 0) { if (deleted > 1) { ReportSuccess(deleted.ToString() + " entities deleted"); } } else { if (deleted > 1) { if (errors > 1) { ReportError("1 entity could not be deleted due to error"); } else { ReportError(errors.ToString() + "entities could not be deleted due to error"); } } } RefreshDetail(tableName); }
8.Entity class implementation
[DataServiceKey("PartitionKey", "RowKey")] public class GenericEntity : TableServiceEntity { string tableName; public string GetTableName() { return tableName; } public void SetTableName(string tableName) { this.tableName = tableName; } Dictionary<string, object> properties = new Dictionary<string, object>(); public Dictionary<string, object> Properties { get { return properties; } set { properties = value; } } public GenericEntity() { } public GenericEntity(GenericEntity e) { this.PartitionKey = e.PartitionKey; this.RowKey = e.RowKey; this.Timestamp = e.Timestamp; this.properties = e.properties; } internal object this[string key] { get { return this.properties[key]; } set { this.properties[key] = value; } } public string Key() { string key = string.Empty; if (RowKey != null) { key = RowKey; } if (PartitionKey != null) { key = PartitionKey + "|" + key; } return key; } public override string ToString() { StringBuilder sb = new StringBuilder(); string value; int count = 0; if (properties != null) { foreach (KeyValuePair<string, object> kvp in properties) { if (count > 0) sb.Append("|"); if (kvp.Value == null) value = string.Empty; else value = kvp.Value.ToString(); sb.Append(kvp.Key + "=" + value); count++; } } return sb.ToString(); } public string ToXml() { StringBuilder sb = new StringBuilder(); sb.AppendLine("<entity>"); sb.AppendLine(" <PartitionKey>" + this.PartitionKey + "</PartitionKey>"); sb.AppendLine(" <RowKey>" + this.RowKey + "</RowKey>"); string value; if (properties != null) { foreach (KeyValuePair<string, object> kvp in properties) { if (kvp.Value == null) value = string.Empty; else value = kvp.Value.ToString(); sb.AppendLine(" <" + kvp.Key + ">" + value + "</" + kvp.Key + ">"); } } sb.Append("</entity>"); return sb.ToString(); } public string ToXmlBinaryValues() { StringBuilder sb = new StringBuilder(); sb.AppendLine("<entity>"); sb.AppendLine(" <PartitionKey>" + this.PartitionKey + "</PartitionKey>"); sb.AppendLine(" <RowKey>" + this.RowKey + "</RowKey>"); string value; if (properties != null) { foreach (KeyValuePair<string, object> kvp in properties) { if (kvp.Value == null) value = string.Empty; else value = kvp.Value.ToString(); value = DisplayCharsAsBytes(value.ToCharArray()); sb.AppendLine(" <" + kvp.Key + ">" + value + "</" + kvp.Key + ">"); } } sb.AppendLine("</entity>"); return sb.ToString(); } /// Convert a byte sequence into a displayable multi-line string showing the values. /// </summary> /// <param name="bytes"></param> /// <returns></returns> private string DisplayBytes(byte[] bytes) { StringBuilder sb = new StringBuilder(); for (int b = 0; b < bytes.Length; b++) sb.Append(String.Format("{0:X2}", bytes[b]) + " "); return sb.ToString(); } private string DisplayCharsAsBytes(char[] chars) { StringBuilder sb = new StringBuilder(); for (int b = 0; b < chars.Length; b++) sb.Append(String.Format("{0:X4}", Convert.ToInt64(char.GetNumericValue(chars[b]))) + " "); return sb.ToString(); } }