1. 新建表(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. 拷贝表(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. 重命名表(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.删除表 (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. 新建实体 (Entity)并插入到表中
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. 更新表(table)中的实体(Entity)
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. 从表(table)中删除实体(Entity)
{
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)类实现
[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();
}
}