zoukankan      html  css  js  c++  java
  • 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中的值不能包含 “/”

       

      
     

  • 相关阅读:
    真的要努力了
    实事求是
    要努力了
    新征程,新目标
    真的要放弃了吗
    集中力量 主攻文科
    May the force be with me.
    记录级排名
    Android开发过程中git、repo、adb、grep等指令的使用
    Ubuntu环境变量设置
  • 原文地址:https://www.cnblogs.com/Qiaoyq/p/2680474.html
Copyright © 2011-2022 走看看