Linq命令查找Azure表存储条目的差异

时间:2015-07-12 15:48:28

标签: .net azure azure-table-storage

我有一个 Azure表存储表,其结构为:

id    date_changed    entity_1    entity_2
 1      May 1 2015        true       false
 2      May 2 2015       false        true
 3      May 3 2015       false       false
 4      May 4 2015        true       false
 5      May 5 2015       false        true
 6      May 7 2015        true       false

我正试图找到一种方法来仅提取entity_1随时间变化的记录(date_changed)。 例如,如果我想要返回entity_1false → true更改的记录或true → false date_changed增加的记录:

 2      May 2 2015        false      true
 4      May 4 2015        true       false
 5      May 5 2015        false      true
 6      May 7 2015        true       false

entity_2

 2      May 2 2015        false      true
 3      May 3 2015        false      false
 5      May 5 2015        false      true
 6      May 7 2015        true       false

我当然可以通过一个循环来实现这一点,但由于我必须遍历所有记录,因此不会真正扩展,并且随着我的表增加记录,这似乎是不可行的。

有没有办法创建Linq查询来查询表存储,只返回entity_1entity_2date_changed增加而变化的记录? < / p>

1 个答案:

答案 0 :(得分:0)

没有办法以可扩展的方式使用像Azure Table这样的键值NoSQL数据库服务来实现所请求的功能。我建议的解决方案是创建两个新表,Entity1TransitionTable和Entity2TransitionTable。该提议是在动态检测转换并在Azure表存储相对便宜的前提下维护这些表中的转换列表。此解决方案假定应用程序始终可以跟踪ID值,并始终以1递增。

  public class LogEntry : TableEntity
  {
     public LogEntry() { }
     public LogEntry(string userid, int id, string date, bool entity1, bool entity2)
     {
        PartitionKey = userid;
        RowKey = id.ToString();
        Id = id;
        Entity1 = entity1;
        Entity2 = entity2;
        Date = date;
     }
     public int Id { get; set; }
     public string Date { get; set; } 
     public bool Entity1 { get; set; }         
     public bool Entity2 { get; set; }         
  }

  static void TransitionDetection(CloudTable tbl, CloudTable e1Tbl, CloudTable e2Tbl, LogEntry currentLogEntry)
  {
     if (currentLogEntry.Id> 1)
     {
        // Retrieve the previous log entry
        string pkFilter = TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, currentLogEntry.PartitionKey);
        string rkFilter = TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.Equal, (currentLogEntry.Id - 1).ToString());
        string combinedFilter = TableQuery.CombineFilters(pkFilter, TableOperators.And, rkFilter);
        TableQuery<LogEntry> query = new TableQuery<LogEntry>().Where(combinedFilter);
        LogEntry prevLogEntry = tbl.ExecuteQuery(query).ToList()[0];

        // If Entity1 transitioned, record it
        if (prevLogEntry.Entity1 != currentLogEntry.Entity1)
        {
           e1Tbl.Execute(TableOperation.Insert(currentLogEntry));
        }

        // If Entity2 transitioned, record it
        if (prevLogEntry.Entity2 != currentLogEntry.Entity2)
        {
           e2Tbl.Execute(TableOperation.Insert(currentLogEntry));
        }
     }
  }

  static void Main(string[] args)
  {
     string storageConnection = "DefaultEndpointsProtocol=https;AccountName=MyTable;AccountKey=MY_KEY";

     // Select table
     CloudStorageAccount storageAccount = CloudStorageAccount.Parse(storageConnection);
     CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
     CloudTable table = tableClient.GetTableReference("LogTable");
     CloudTable entity1TransitionTable = tableClient.GetTableReference("Entity1TransitionTable");
     CloudTable entity2TransitionTable = tableClient.GetTableReference("Entity2TransitionTable");
     table.CreateIfNotExists();
     entity1TransitionTable.CreateIfNotExists();
     entity2TransitionTable.CreateIfNotExists();

     // Add Log Entries
     int id = 0;

     LogEntry le1 = new LogEntry("0", ++id, "May 1 2015", true, false);
     TransitionDetection(table, entity1TransitionTable, entity2TransitionTable, le1);
     table.Execute(TableOperation.Insert(le1));

     LogEntry le2 = new LogEntry("0", ++id, "May 2 2015", false, true);
     TransitionDetection(table, entity1TransitionTable, entity2TransitionTable, le2);
     table.Execute(TableOperation.Insert(le2));

     LogEntry le3 = new LogEntry("0", ++id, "May 3 2015", false, false);
     TransitionDetection(table, entity1TransitionTable, entity2TransitionTable, le3);
     table.Execute(TableOperation.Insert(le3));

     LogEntry le4 = new LogEntry("0", ++id, "May 4 2015", true, false);
     TransitionDetection(table, entity1TransitionTable, entity2TransitionTable, le4);
     table.Execute(TableOperation.Insert(le4));

     LogEntry le5 = new LogEntry("0", ++id, "May 5 2015", false, true);
     TransitionDetection(table, entity1TransitionTable, entity2TransitionTable, le5);
     table.Execute(TableOperation.Insert(le5));

     LogEntry le6 = new LogEntry("0", ++id, "May 7 2015", true, false);
     TransitionDetection(table, entity1TransitionTable, entity2TransitionTable, le6);
     table.Execute(TableOperation.Insert(le6));

     Console.ReadKey();
  }

如果使用TableXplorer等应用程序检查表,您将看到以下结果:

LogTable

enter image description here

Entity1TransitionTable

enter image description here

Entity2TransitionTable

enter image description here