【问题标题】:Make existing entity implement TableEntity使现有实体实现 TableEntity
【发布时间】:2013-12-29 21:18:26
【问题描述】:

我正在尝试为 Azure 表存储创建通用 CRUD 服务。

过去,我一直使用带有实体框架的存储库/工作单元模式的 SQL。我希望 Azure 表存储也有同样的功能,但我看到的所有示例都要求我的实体从 Azure 库中实现 TableEntity。

但对我来说,这与 SOLID 原则相冲突 - 因为我的存储库和我的模型不需要了解 Azure 即可工作。

所以我想要的是一个我也传递一个实体的服务,并且该服务改变所述类以使其实现 TableEntity 从而允许我运行通常的 TableStorage CRUD 操作,将它映射回我的实体类并返回它。

【问题讨论】:

    标签: c# azure repository-pattern azure-table-storage


    【解决方案1】:

    我编写了一个通用 API,它通过使用递归反射展平复杂对象来完成从任何复杂对象到 EntityProperty 字典的转换。然后,您可以将实体属性字典作为 DynamicTableEntity 写入 Azure 表存储。

    当您读取 DynamicTableEntity 时,API 将转换回复杂对象。

    此 API 的强大之处在于它适用于任何具有嵌套属性的复杂对象,这些对象本身可能是具有其他嵌套属性的复杂对象。

    随意看看和使用:)https://www.nuget.org/packages/ObjectFlattenerRecomposer/

    用法:

    //Flatten object of type Order) and convert it to EntityProperty Dictionary
     Dictionary<string, EntityProperty> flattenedProperties = ObjectFlattenerRecomposer.Flatten(order);
    
    // Create a DynamicTableEntity and set its PK and RK
    DynamicTableEntity dynamicTableEntity = new DynamicTableEntity(partitionKey, rowKey);
    
    dynamicTableEntity.Properties = flattenedProperties;
    
    // Write the DynamicTableEntity to Azure Table Storage using client SDK
    
    
    //Read the entity back from AzureTableStorage as DynamicTableEntity using the same PK and RK
    
    DynamicTableEntity entity = [Read from Azure using the PK and RK];
    
    //Convert the DynamicTableEntity back to original complex object.    
    Order order = ObjectFlattenerRecomposer.ConvertBack<Order>(entity.Properties);
    

    就是这样:)

    【讨论】:

      【解决方案2】:

      我自己想通了。我使用了一个实现 ITableEntity 要求的动态对象。

      如果有人感兴趣,我在这里写了一篇关于我是如何做到的博客。

      http://bretthargreaves.wordpress.com/2014/01/11/azure-table-storage-with-repository-pattern/

      【讨论】:

      • 有人有适用于新 Azure.Data.Tables sdk 的有效动态方法吗?
      【解决方案3】:

      这是一种更简单的方法,您可以像添加系统列 PartitionKey、RowKey、Timestamp 和 ETag 一样创建模型。

      public class LogModel
      {
          public string LogMessage { get; set; }
      
          public string PartitionKey { get;set;}
          public string RowKey { get; set; }
          public DateTimeOffset Timestamp { get; set; }
          public string ETag { get; set; }
      }
      

      此模型没有对 AzureTables 的任何引用,因此我们将其保持为 SOLID。

      然后我们创建存储库并在其中创建一个 LogEntityWrapper,这将有助于使用 Azure 表。

      public class LogRepository : ILogRepository
      {
          protected CloudTable table;
          //ctor that initialize the azure table
          public LogRepository(string tableName, string connectionString)
          {
              if (string.IsNullOrEmpty(tableName) || string.IsNullOrEmpty(connectionString))
                  throw new ArgumentException()
      
              var storageAccount = CloudStorageAccount.Parse(connectionString);
              var tableClient = storageAccount.CreateCloudTableClient();
      
              table = tableClient.GetTableReference(tableName);
              table.CreateIfNotExists();
          }
          //read from table and Cast the rows to LogModel
          public IEnumerable<LogModel> GetLogs()
          {
              var query = new TableQuery<LogEntityWrapper>();
              var entities = table.ExecuteQuery(query);
              //The Cast doesn't break laziness
              return entities.Cast<LogModel>();
          }
      
          // A minimal wrapper, just the implementations of Read and Write Entity
          private class LogEntityWrapper : LogModel, ITableEntity
          {
              public void ReadEntity(IDictionary<string, EntityProperty> properties, OperationContext operationContext)
              {
                  TableEntity.ReadUserObject(this, properties, operationContext);
              }
      
              public IDictionary<string, EntityProperty> WriteEntity(OperationContext operationContext)
              {
                  return TableEntity.WriteUserObject(this, operationContext);
              }
          }
      }
      

      【讨论】:

      • 您好,ExecuteQuery 不再可用,现在是 ExecuteQuerySegmentedAsync 有没有办法投射?
      • 以及如何使用您的代码插入新的 TableEntity?
      猜你喜欢
      • 1970-01-01
      • 2017-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多