Windows Azure 中如何在TableStorage中存取数据

   在Windows Azure 中,数据的存储主要有三种格式:Blob,TableStorage, SqlAzure。在本节中,主要介绍如何将Entity存入TableStorage 中,或者将TableStorage的数据转换成相应的Entity。

   一个TableStorage其实就是一个数据表,在该表中,有两个关键字段:PartitionKey 和 RowKey,这两个字段要能够唯一确定一条记录。

   下边首先讲如何将对应的Entity 数据存入TableStorage中。

    要想将Entity存入TableStorage中,这个Entity必须继承自:TableServiceEntity 类。

    下边是TableServiceEntity类的代码结构:

   

namespace Microsoft.WindowsAzure.StorageClient
{
    // Summary:
    //     Represents an entity in the Windows Azure Table service.
    [CLSCompliant(false)]
    public abstract class TableServiceEntity
    {
        // Summary:
        //     Initializes a new instance of the Microsoft.WindowsAzure.StorageClient.TableServiceEntity
        //     class.
        protected TableServiceEntity();
        //
        // Summary:
        //     Initializes a new instance of the Microsoft.WindowsAzure.StorageClient.TableServiceEntity
        //     class.
        //
        // Parameters:
        //   partitionKey:
        //     The partition key.
        //
        //   rowKey:
        //     The row key.
        protected TableServiceEntity(string partitionKey, string rowKey);

        // Summary:
        //     Gets or sets the partition key of a table entity.
        public virtual string PartitionKey { get; set; }
        //
        // Summary:
        //     Gets or sets the row key of a table entity.
        public virtual string RowKey { get; set; }
        //
        // Summary:
        //     Gets or sets the timestamp for the entity.
        public DateTime Timestamp { get; set; }
    }
}

从代码中可以看到,这个类有三个字段 PartitionKey,RowKey,Timestamp。这三个字段和tableStorage中的字段是一一对应的。如果一个实体要保存到 TableStorage中,PartitionKey,RowKey不能为空,且不能和TableStorage中已有的记录重复。

      下边我们 写一个类 让其继承自 TableServiceEntity

View Code
namespace RF.Integration.Common
{
    public class LogBase : TableServiceEntity
    {

        private string externalSystemName;
        private string batchNum;
        private int pageCount;
        private int pageIndex;

        public string ExternalSystemName
        {
            get { return externalSystemName; }
            set { externalSystemName = value; }

        }

        public string BatchNum
        {
            get { return batchNum; }
            set { batchNum = value; }

        }

        public int PageCount
        {
            get { return pageCount; }
            set { pageCount = value; }
        }

        public int PageIndex
        {
            get { return pageIndex; }
            set { pageIndex = value; }
        }

    }
}

      在我的实际项目中,LogBase类是一个父类,其下边有三个子类。如下的UploadLogInfo是其中的一个子类

View Code
namespace RF.Integration.Common
{
    public class UploadLogInfo : LogBase
    {
   
      private string fileSchemaVersion;
      private string fileName;
      private string fileSize;
      private string saveName;
      private string startUploadTime;
      private string endUploadTime;
      private string endStatus;
      private string errorInfo;

     

      public string FileSchemaVersion
      {
          get { return fileSchemaVersion; }
          set { fileSchemaVersion = value;}
      }

      public string FileName
      {
          get { return fileName; }
          set { fileName = value; }
      
      }

      public string FileSize
      {
          get { return fileSize; }
          set { fileSize = value; }
      
      }

      public string SaveName
      {
          get { return saveName;}
          set { saveName = value; }
      
      }


      public string StartUploadTime
      {
          get { return startUploadTime;}
          set { startUploadTime = value;}
      
      }
      public string EndUploadTime
      {
          get { return endUploadTime; }
          set {  endUploadTime=value; }
      }
      public string EndStatus
      {
          get { return endStatus; }
          set { endStatus = value; }
      }
      public string ErrorInfo
      {
          get { return errorInfo; }
          set { errorInfo = value;}
      }


      public void InitUploadLogInfo(RemoteFileInfo remoteFileInfo)
      {
          this.ExternalSystemName = remoteFileInfo.externalSystemName.ToLower();
          this.FileSchemaVersion = remoteFileInfo.SchemaVersion;
          this.FileName = remoteFileInfo.fileName;
          this.BatchNum = remoteFileInfo.batchInfo.ToString("N");
          this.PageCount =int.Parse(remoteFileInfo.pageCount);
          this.PageIndex =int.Parse(remoteFileInfo.pageIndex);

      }


    }
}

    下边向大家提供一个LogProvider类,用于将上述所说的Log类信息保存到 TableStorage中
     

View Code
namespace RF.Integration.Common
{
   public class LogProvider
    {
       TableHelper tableHelper;

       private static LogProvider logProvider;

       private LogProvider()
        {
#if DEBUG
            tableHelper = new TableHelper();
#else
            tableHelper = new TableHelper(ConstLib.STORAGE_CONNECTION_STR,true);
#endif
        }

       public static LogProvider CreatInstance()
       {
           object _lock = new object();
           if (logProvider == null)
           {
               lock (_lock)
               {
                   if (logProvider == null)
                   {
                       logProvider = new LogProvider();
                   }
               }
           
           }
           return logProvider;
       }

       public void SaveLog<T>(T logInfo) where T : LogBase
       {
           string tableName="";
           if (logInfo is UploadLogInfo)
           { 
             tableName=ConstLib.AZURE_UPLOADLOG_TABLE;
           }
           if(logInfo is CompareLogInfo)
           {
             tableName=ConstLib.AZURE_COMPARELOG_TABLE;
           }
           if (logInfo is DownLoadLogInfo)
           {
               tableName = ConstLib.AZURE_DownLoadLog_TABLE;
           }

           if (String.IsNullOrEmpty(logInfo.PartitionKey))
           {
               logInfo.PartitionKey = logInfo.ExternalSystemName;
           }

           if (String.IsNullOrEmpty(logInfo.RowKey))
           {
               logInfo.RowKey = String.Format("{0}-{1}-[{2}-{3}]", logInfo.BatchNum,DateTime.Now.ToString("yyyyMMddHHmmss"), logInfo.PageCount, logInfo.PageIndex);
           }

           if (!string.IsNullOrEmpty(tableName) && !string.IsNullOrEmpty(logInfo.PartitionKey) && !string.IsNullOrEmpty(logInfo.RowKey))
           {

               if (GetLogInfo<T>(logInfo) == null)
               {
                   tableHelper.InsertEntity(tableName, logInfo);
               }
               else
               {
                   tableHelper.ReplaceUpdateEntity<T>(tableName, logInfo.PartitionKey, logInfo.RowKey, logInfo);
               }
           }
       }

     
       public T GetLogInfo<T>(T logInfo) where T : TableServiceEntity
       {
           string tableName = "";
           if (logInfo is UploadLogInfo)
           {
               tableName = ConstLib.AZURE_UPLOADLOG_TABLE;
           }
           if (logInfo is CompareLogInfo)
           {
               tableName = ConstLib.AZURE_COMPARELOG_TABLE;
           }
           if (logInfo is DownLoadLogInfo)
           {
               tableName = ConstLib.AZURE_DownLoadLog_TABLE;
           }

           TableHelper tableHelper;
#if DEBUG
            tableHelper = new TableHelper();
#else
            tableHelper = new TableHelper(ConstLib.STORAGE_CONNECTION_STR,true);
#endif

            T rtnLogInfo = tableHelper.QueryEntitiesByPartitionAndRowKey<T>(tableName, logInfo.PartitionKey, logInfo.RowKey).FirstOrDefault();

           return rtnLogInfo;
       }

    }
}

    从代码中可以看到,该类提供两个方法,SaveLog 和 GetLogInfo,分别用来存储和读取log信息。

其中引用到的TableHelper类中的两个方法如下,这也是我们这节的核心方法

View Code
 public bool ReplaceUpdateEntity<T>(string tableName, string partitionKey, string rowKey, T obj) where T : TableServiceEntity
        {
            try
            {
                TableServiceContext tableServiceContext = TableClient.GetDataServiceContext();
                tableServiceContext.IgnoreResourceNotFoundException = true;
                IQueryable<T> entities = (from e in tableServiceContext.CreateQuery<T>(tableName)
                                          where e.PartitionKey == partitionKey && e.RowKey == rowKey
                                          select e);

                T entity = entities.FirstOrDefault();

                Type t = obj.GetType();
                PropertyInfo[] pi = t.GetProperties();

                foreach (PropertyInfo p in pi)
                {
                    p.SetValue(entity, p.GetValue(obj, null), null);
                }

                tableServiceContext.UpdateObject(entity);
                tableServiceContext.SaveChanges(SaveChangesOptions.ReplaceOnUpdate);

                return true;
            }
            catch (DataServiceRequestException)
            {
                return false;
            }
            catch (StorageClientException ex)
            {
                if ((int)ex.StatusCode == 404)
                {
                    return false;
                }

                throw;
            }
        }
View Code
public List<T> QueryEntitiesByPartitionAndRowKey<T>(string tableName, string partitionKey, string rowKey) where T : TableServiceEntity
        {
            CreateTableIfNotExist(tableName);
            TableServiceContext tableServiceContext = TableClient.GetDataServiceContext();
            tableServiceContext.IgnoreResourceNotFoundException = true;
            List<T> entities = new List<T>();
            try
            {
                entities = (from e in tableServiceContext.CreateQuery<T>(tableName)
                            where e.PartitionKey == partitionKey && e.RowKey == rowKey
                            select e).AsTableServiceQuery<T>().ToList();
            }
            catch
            { }
            return entities;
        }

 另外需要注意的是:PartitionKey,RowKey中的值不能包含 “/”

   

  
 

 

转载于:https://www.cnblogs.com/Qiaoyq/archive/2012/09/11/2680474.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值