2013-10-23 59 views
4

我在我的應用程序中有(幾乎)所有POCO類的主基類。使用Redis,密鑰或Id存儲對象標識符?

public abstract class AceOfBase 
{ 
    public long Id { get; set; } 
    public DateTimeOffset CreatedOn { get; set; } 
    public string Key { get; set; } 
} 

我的一些主要類別(Member , Building, Community, etc.)的具有特性的相當數量如此 我打算採取簡單的管理ServiceStack'sStrongly-Typed Client提供的優勢。

From the research I've done看來,客戶端使用結構化方法用於創建密鑰

基本上波蘇斯被存儲到Redis的作爲既將typeof序列化JSON(波科),請將.Name和ID用來形成一個獨特的密鑰就此而言。例如:

甕:波索:{ID} => '{ 「ID」:1, 「富」: 「酒吧」}'

因爲有時我將檢索對象繼承基類(但我不知道編譯時的派生類)我怎樣才能最好地存儲密鑰,以便我可以輕鬆地獲得任何對象?

一個理想的世界中,我將能夠配置RedisClientRedisTypedClient使用鑰匙相同的命名約定,但我沒有發現任何東西,讓我做這個(還)和文件上的各個方法是很難得由兩個客戶。

回答

1

在挖掘完ServiceStack程序集之後,我發現強類型客戶端的Store()方法實際上只是SetEntry(key,value)和一個用於生成密鑰結構的實用程序方法。

實用方法IdUtils.CreateUrn有一些重載,可讓您指定TypeId,然後返回一個用作鍵的字符串。

我做了什麼的話,寫在我的庫基類CreateKey方法創建的任何AceOfBase對象時,我然後調用並將其設置爲Key

//In BaseRepository 
public virtual string CreateKey<T>(T entity) where T : AceOfBase 
{ 
return IdUtils.CreateUrn<AceOfBase>(entity.Id); 
} 

//In MemberRepository 
Member m = new Member(); //inherits from AceOfBase 
m.Key = CreateKey(m); 

我在我的應用程序實現了兩個臺班爲好,這些幫助我利用Redis的快瘋了查詢時間,同時讓我正常使用的關係,因爲我將與EF。

  1. DomainModels - 這些看起來像在它們的性質是傳統結構正常上課。

    public class Activity : AceOfBase 
    { 
        public AceOfBase IndirectObject { get; set; } 
        public Participant Predicate { get; set; } 
        public Participant Subject { get; set; } 
        public Verb Verb { get; set; } 
    } 
    
  2. DataModels - 這些包含相同的原始和枚舉作爲他們的DomainModel同行,但如果一個字段是存儲在Redis的自定義類型是用字符串(具有相同的屬性名)代表該對象的關鍵。

    public class Activity : AceOfBase 
    { 
        public string IndirectObject { get; set; } 
        public string Predicate { get; set; } 
        public string Subject { get; set; } 
        public Verb Verb { get; set; } 
    } 
    

我已經實現AutoMapper與一組自定義TypeConverter類,做在DomainModel轉換DataModel字符串屬性到相應的屬性具有相同名稱的繁重工作。 AutoMapper然後在存儲任何對象之前以及在從Redis中提取對象並在兩種模型類型之間進行轉換之後立即被調用。

//In Configure() 
Mapper.CreateMap<string,Member>().ConvertUsing<KeyToBaseConverter<Member>>(); 
Mapper.CreateMap<Member, string>().ConvertUsing<BaseToKeyConverter<Member>>(); 

public class KeyToBaseConverter<T> : ITypeConverter<string, T> where T : AceOfBase 
{ 
    public RedisRepository Repository { get; set; } 
    public T Convert(ResolutionContext context) 
    { 
     return Repository.GetByKey<T>(context.SourceValue.ToString()); 
    } 
} 
public class BaseToKeyConverter<T> : ITypeConverter<T, string> where T : AceOfBase 
{ 
    public string Convert(ResolutionContext context) 
    { 
     var f = context.SourceValue as AceOfBase; 
     return f.Key; 
    } 
} 

留下地址的唯一部件是確保我創建任何ListsSets獲得其關鍵相同的格式。

使用此模式,我將能夠在字符串客戶端旁邊無縫地使用強類型客戶端,確保即使在沒有強類型客戶端的情況下拉對象,我也可以確定並安全地將JSON blob轉換爲正確的類型通過只檢查關鍵屬性。