使用Redis,密钥或Id存储对象标识符?

时间:2013-10-23 21:57:55

标签: c# redis servicestack

我的(几乎)我的应用程序中的所有POCO类都有一个主基类。

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

我的一些主要课程(Member , Building, Community, etc.)拥有相当数量的属性 我计划利用ServiceStack's Strongly-Typed Client提供的简便管理。

From the research I've done客户似乎使用结构化方法来创建密钥

  

基本上,POCO作为序列化JSON存储到Redis中,其中typeof(Poco).Name和Id用于形成该实例的唯一键。 E.g:

     

urn:Poco:{Id} => '{ “ID”:1, “富”: “酒吧”}'

因为有时我会检索一个继承基类的对象(但我不知道编译时的派生类)如何才能最好地存储密钥以便我可以获得任何容易对象?

一个理想的世界我可以配置RedisClientRedisTypedClient使用相同的键命名约定,但我还没有找到任何可以让我这样做(还)和文档的对于两个客户来说,很难找到个人方法。

1 个答案:

答案 0 :(得分:1)

在深入了解ServiceStack程序集后,我发现强类型客户端的Store()方法实际上只是SetEntry(key,value),其实用方法用于生成密钥结构。

实用程序方法IdUtils.CreateUrn有一些重载,可让您指定TypeId,然后返回用作键的字符串。

然后,我在我的Repository基类中编写了一个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; }
    }
    
  3. 我已经使用一组自定义AutoMapper类实现了TypeConverter,它们将DataModel字符串属性转换为{{1}中具有相同名称的相应属性}。然后在存储任何对象之前以及从Redis中提取对象并在两种模型类型之间进行转换之后立即调用DomainModel

    AutoMapper

    唯一要解决的问题是确保我创建的任何//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; } } Lists为其密钥设置相同的格式。

    使用此模式,我将能够在字符串客户端旁边无缝地使用强类型客户端,确保即使在没有强类型客户端的情况下拉动对象,我也可以确定并安全地将JSON blob转换为正确的Type仅检查Key属性。