【问题标题】:Using ServiceStack OrmLite to create Key Value table for dynamic types使用 ServiceStack OrmLite 为动态类型创建 Key Value 表
【发布时间】:2014-09-30 20:43:16
【问题描述】:

我想在我的数据库中创建一个键值表

public class KeyValue { 
    public string Id { get; set; }
    public dynamic Value {get; set; }
}

使用稍作修改的 SqlProvider 让 CreateTable<KeyValue>() 生成 varchar(1024) Id、varchar(max) Value 没有问题。

我没有问题将对象保存到它。问题是当我加载对象时

var content = dbConn.GetById<KeyValue>("about");

content.Value此时是一个字符串。

查看数据库记录,value 的文本似乎没有存储任何类型信息。

除了手动调用ServiceStack.Text 并使用适当的类型信息调用反序列化之外,我真的有什么可以做得更好的吗?

我不需要绝对动态,我的实际用例是使用基类而不是动态的多态性。所以我真的不在乎Value是什么类型,是基类、动态、对象等等。不管是用类还是别的

public class KeyValue { 
    public string Id { get; set; }
    public MySpecificChildType Value {get; set; }
}

除了返回 Value 的字符串外,我什么也得不到。我可以告诉 OrmLite 序列化类型信息以便能够正确反序列化我的对象,还是我只需要手动完成?

编辑:一些进一步的信息。 OrmLite 使用由 ServiceStack.Text.TypeSerializer 定义的 Jsv 序列化程序,并且在 BSD 版本中绝不可插入。如果我使用动态值将 Type 属性添加到我的 KeyValue 类中,我可以这样做

var value = content.Value as string;
MySpecificChildType strongType = 
                TypeSerializer.DeserializeFromString(content, content.Type);

我只是真的想要一种更好的方法来做到这一点,我真的不喜欢进入数据库的 1 类型的对象以不同的类型(字符串)返回。

【问题讨论】:

    标签: c# .net dynamic ormlite-servicestack servicestack-bsd


    【解决方案1】:

    我对 JsvSerializer 的工作并不多,但使用 JsonSerializer 您可以实现这一点(通过几种不同的方式),从 ServiceStack 4.0.11 开始,您可以选择使用 JsonSerializer,请参阅 https://github.com/ServiceStack/ServiceStack/blob/master/release-notes.md#v4011-release-notes。

    例子

    public abstract class BaseClass {
        //Used for second example of custom type lookup
        public abstract string Type { get; set; }
    }
    
    public class ChildA : BaseClass {
        //Used for second example of custom type lookup
        public override string Type { get; set; }
    
        public string PropA { get; set; }
    }
    

    然后在您的 init/bootstrap 类中,您可以配置序列化程序以发出正确反序列化所需的类型信息:

    public class Bootstrapper {
        public void Init() {
            ServiceStack.Text.JsConfig.ExcludeTypeInfo = false;
            ServiceStack.Text.JsConfig.IncludeTypeInfo = true;
        }
    }
    

    如果您希望使用 ServiceStack 使用的默认“__type”属性以外的其他内容(例如,如果您希望使用一个友好的名称来标识类型而不是命名空间/程序集),您还可以将自己的自定义类型查找配置为这样的

    public class Bootstrapper {
        public void Init() {
            ServiceStack.Text.JsConfig.ExcludeTypeInfo = false;
            ServiceStack.Text.JsConfig.IncludeTypeInfo = true;
    
            ServiceStack.Text.JsConfig.TypeAttr = "type";
            ServiceStack.Text.JsConfig.TypeFinder = type =>
            {
                if ("CustomTypeName".Equals(type, StringComparison.OrdinalIgnoreCase))
                {
                    return typeof(ChildA);
                }
    
                return typeof(BaseClass);
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-05
      • 1970-01-01
      • 1970-01-01
      • 2022-01-18
      • 2015-05-28
      相关资源
      最近更新 更多