2016-09-22 4 views
0

фоновойAzure TableEntity - Hooking для чтения/записи операций

Предполагая, что у меня есть Azure Table Entity

class MyEntity : TableEntity 
{ 
    public string LongString { get; set; } 
    public bool IsCompressed { get; set; } 
} 

И если LongString> 64KB (Azure ограничения на собственность), я хочу, чтобы сохранить LongString сжимается. Для этого у меня есть 2 функции Compress(string) и Decompress(string)

В настоящее время перед каждым вкладышем я проверяю длину LongString и если это> 64KB, я устанавливаю LongString = Compress(LongString) и IsCompressed = true. Противоположность после каждой операции Azure.

Я хочу скрыть вариант сжатия от всего кода и обеспечить саморазложение сжатия и декомпрессии в классе MyEntity.

Вопрос

Есть ли возможность сделать пользовательские операции до и после получения и установки объектов из лазурной таблицы? Что-то вроде ...

class MyEntity : TableEntity 
{ 
    public string LongString { get; set; } 
    public string IsCompressed { get; set; } 

    public override void BeforeInsert() 
    { 
     if (LongString.Length > 64KB) 
     { 
      LongString = Compress(LongString); 
      IsCompressed = true; 
     } 
    } 

    public override void AfterGet() 
    { 
     if (IsCompressed) 
     { 
      LongString = Decompress(LongString); 
      IsCompressed = false; 
     } 
    } 
} 
+1

Один несовершеннолетний не по теме комментарий: Дано Azure использует UTF16 для кодирования данных и, таким образом, использует 2 байта, чтобы сохранить каждый байт данных, которые предоставляют, предел фактически 32KB вместо 64KB. Думаю, я должен упомянуть об этом. –

ответ

1

Нашли решение, используя функции ReadEntity и WriteEntity.

class MyEntity : TableEntity 
{ 
    public string LongString { get; set; } 
    public bool IsCompressed { get; set; } 

    public override void ReadEntity(IDictionary<string, EntityProperty> properties, OperationContext operationContext) 
    { 
     base.ReadEntity(properties, operationContext); 

     if (IsCompressed) 
     { 
      LongString = Decompress(LongString); 
      IsCompressed = false; 
     } 
    } 

    public override IDictionary<string, EntityProperty> WriteEntity(OperationContext operationContext) 
    { 
     if (LongString.Length > 64KB) 
     { 
      LongString = Compress(LongString); 
      IsCompressed = true; 
     } 

     return base.WriteEntity(operationContext); 
    } 
} 
0

Возможность может быть что-то вроде следующего кода:

public bool IsCompressed; 

public string StoredString { get; set; } 

private string longString; 

[IgnoreProperty] 
public string LongString 
{ 
    get 
    { 
     if (this.longString == null) 
     { 
      if (IsCompressed) 
      { 
       this.longString = DeCompress(StoredString); 
      } 
      else 
      { 
       this.longString = StoredString; 
      } 
     } 
     return this.longString; 
    } 
    set 
    { 
     if (longString != value) 
     { 
      this.longString = value; 
      if (this.longString.Length > 64KB) 
      { 
       IsCompressed = true; 
       this.StoredString = Compress(this.longString); 
      } 
     } 
    } 
} 

Но спросите себя, если это не проще, всегда сохранять сжатую строку.

+0

1. Моя проблема с этим решением состоит в том, что у меня будет 2 свойства с одним и тем же именем [L/l] ongString, и я не буду знать, что является декомпрессированным. 2. Причина не прессования всегда доступна для чтения в приложениях в лазурной таблице, когда она не слишком длинная (большую часть времени). – motcke

+0

Хорошо, это действительно верная причина. –

1

Вам не нужна такая сложность, что вы можете просто создать рассчитанные свойства для записи в хранилище таблиц. И вам также не нужны несколько свойств. Следовательно, нет необходимости иметь второе свойство с атрибутом IgnoreProperty. Я напечатал ниже в текстовом редакторе, но это должно дать вам эту идею.

private string longString; 

public bool IsCompressed { get; set; } 

public string LongString 
{ 
    get 
    { 
     return IsCompressed ? DeCompress(longString) : longString; 
    } 
    set 
    { 
     if (String.IsNullOrWhiteSpace(value) || value.Length < 64KB) 
     { 
      IsCompressed = false; 
      longString = value; 
     } 
     else (value.Length > 64KB) 
     { 
      IsCompressed = true; 
      longString = Compress(value); 
     } 
    } 
} 
Смежные вопросы