如何在ServiceStack.OrmLite中自定义复杂类型的序列化/反序列化

Erw*_*yer 7 c# servicestack nodatime ormlite-servicestack servicestack-text

我正在使用ServiceStack.OrmLite将数据保存在SQLite数据库中,并且到目前为止对此非常满意.

但是,我的许多对象都具有复杂类型的属性,我不想将其序列化使用JSV.

我需要能够指定应该用于在数据库中存储属性的自定义序列化/反序列化(作为字符串).在db4o世界上,这相当于使用由提供的翻译功能IObjectConstructor.

无法正确序列化和反序列化的复杂类型的一个很好的例子是NodaTime类型,即使它们可以很容易地映射到字符串(我已经拥有了我使用的序列化/反序列化函数db4o).

实现这一目标的最简单方法是什么?包装器不是很方便,因为我必须为包含这种复杂类型属性的每种类型编写和维护一个包装器.

Erw*_*yer 6

对于那些可能对包装模式感兴趣的人,我目前正在使用OrmLite实现自定义序列化(也可以与其他ORM一起使用),这里有一个简单的工作示例,其中的NodaTime类型不能正确地序列化:

public class BusinessObject {
    public class Poco {
        public readonly BusinessObject BusinessObject;

        public Poco(BusinessObject businessObject) {
            this.BusinessObject = businessObject;
        }

        public Poco() {
            this.BusinessObject = new BusinessObject();
        }

        public string Id {
            get { return this.BusinessObject.Id; }
            set { this.BusinessObject.Id = value; }
        }

        public decimal Amount {
            get { return this.BusinessObject.Amount; }
            set { this.BusinessObject.Amount = value; }
        }

        public DateTime Dt {
            get { return this.BusinessObject.Dt.ToDateTime(); }
            set { this.BusinessObject.Dt = LocalDateTime.FromDateTime(value).Date; }
        }

        public string TimeZone {
            get { return this.BusinessObject.TimeZone.Id; }
            set { this.BusinessObject.TimeZone = DateTimeZoneProviders.Tzdb.GetZoneOrNull(value); }
        }

        public string Description {
            get { return this.BusinessObject.Description; }
            set { this.BusinessObject.Description = value; }
        }
    }

    public string Id { get; private set; }
    public decimal Amount { get; private set; }
    public LocalDate Dt { get; private set; }
    public DateTimeZone TimeZone { get; private set; }
    public string Description { get; private set; }

    public BusinessObject() { }

    public BusinessObject(string id, decimal amount, LocalDate dt, DateTimeZone timeZone, string description) {
        this.Id = id;
        this.Amount = amount;
        this.Dt = dt;
        this.TimeZone = timeZone;
        this.Description = description;
    }
}
Run Code Online (Sandbox Code Playgroud)

我希望很快就可以为应该使用自定义代码处理的特定类型定义钩子/回调,并且OrmLite将允许具有私有setter的属性从持久性重新加载(目前它只能在一个方向上工作).

更新(2014/03/08):作为临时解决方法,可以通过先调用OrmLite使用自定义序列化/反序列化:

JsConfig<BusinessObject>.TreatValueAsRefType = true;
Run Code Online (Sandbox Code Playgroud)

即使BusinessObject是参考类型.然后,您可以享受美丽/简单/无处不在:

JsConfig<BusinessObject>.RawSerializeFn = bo => bo.Serialize();
JsConfig<BusinessObject>.RawDeserializeFn = str => BusinessObject.Deserialize(str);
Run Code Online (Sandbox Code Playgroud)

希望很快就会添加对自定义映射的支持(例如,可以将NodaTime.LocalDate映射到DateTime而不是字符串).