7

我正在使用ServiceStack.OrmLite將數據保存在SQLite數據庫中,並且迄今爲止還很滿意。如何自定義ServiceStack.OrmLite中複雜類型的序列化/反序列化

但是,我的許多對象具有複雜類型的屬性,我不想使用JSV進行序列化。

我需要能夠指定應該用於在數據庫中存儲屬性的自定義序列化/反序列化(作爲字符串)。在db4o世界中,這將等同於使用IObjectConstructor提供的翻譯功能。

無法正確序列化和反序列化的複雜類型的一個很好的例子是NodaTime類型,儘管它們可以很容易地映射到字符串(我已經有了與db4o一起使用的序列化/反序列化函數)。

實現該目標的最簡單方法是什麼?包裝器不會很方便,因爲我必須爲每個包含此複雜類型屬性的類型編寫和維護一個包裝器。

+0

請給一個一個班的最低工作實例,你想如何實現它,以及如何去除它。 – htellez

+0

這很簡單,我有一個屬性類型複雜的基礎類。我需要使用我自己的例程而不是JSV將該屬性序列化/反序列化到/從字符串中。我不認爲在這個特定的實例中真的需要代碼示例。 –

回答

6

//ServiceStack's JSON and JSV Format 
SqliteDialect.Provider.StringSerializer = new JsvStringSerializer();  
PostgreSqlDialect.Provider.StringSerializer = new JsonStringSerializer(); 
//.NET's XML and JSON DataContract serializers 
SqlServerDialect.Provider.StringSerializer = new DataContractSerializer(); 
MySqlDialect.Provider.StringSerializer = new JsonDataContractSerializer(); 
//.NET XmlSerializer 
OracleDialect.Provider.StringSerializer = new XmlSerializableSerializer(); 

您也可以通過實施 IStringSerializer提供自定義的序列化策略對於那些可能對我目前用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; 
    } 
} 

我希望它會很快就可以定義應與自定義代碼來處理特定類型的鉤/回調,同時又有OrmLite將允許私人setter方法的屬性要從持久性中重新加載(目前它只能在一個方向上工作)。

更新(2014年3月8日):作爲臨時解決辦法,有可能通過調用第一有OrmLite使用自定義序列化/反序列:

JsConfig<BusinessObject>.TreatValueAsRefType = true; 

即使BusinessObject是引用類型。然後,你可以享受的美容/簡單/無所不在:

JsConfig<BusinessObject>.RawSerializeFn = bo => bo.Serialize(); 
JsConfig<BusinessObject>.RawDeserializeFn = str => BusinessObject.Deserialize(str); 

自定義映射希望支持我們會盡快添加(以便例如NodaTime.LocalDate可以映射爲DateTime,而不是字符串)。

+0

我真的沒有看到私人設定者如何從外部加載,或者他們應該如何加載。儘管如此,受保護的方式仍然有效。 – ANeves

+1

私人二傳手可以通過Reflection獲得。 –

2

OrmLite現在支持pluggable text serializers

可插拔的序列化可以讓你爲每個可用的RDBMS提供商指定複雜類型的不同的系列化的策略,如:

public interface IStringSerializer 
{ 
    To DeserializeFromString<To>(string serializedText); 
    object DeserializeFromString(string serializedText, Type type); 
    string SerializeToString<TFrom>(TFrom from); 
} 
2

要在JsConfig序列化複雜類型,設置自己的串行器(及解串器):

JsConfig<Foo>.SerializeFn = foo => foo.ToString("XOXO", CultureInfo.InvariantCulture); 
JsConfig<Foo>.DeSerializeFn = foo => 
{ 
    var result = Foo.Parse(foo, CultureInfo.InvariantCulture); 
    return result; 
}; 

您也可能想告訴JsConfig承擔UTC日期:

JsConfig.AssumeUtc = true; 
+0

這是否與OrmLite兼容?我知道它適用於ServiceStack,但就我閱讀並測試過的代碼而言,OrmLite序列化沒有考慮到它。 –

+0

它的確如此。但是我遇到[結構序列化的麻煩](http://stackoverflow.com/questions/20246508/make-ormlite-use-proper-serialization-for-structs)。 (反序列化工作正常,對於引用類型,它們都可以很好地進行序列化和反序列化。) – ANeves