1

I want to create a key value table in my database along the lines of

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

Using a slightly modified SqlProvider I have no problems getting CreateTable<KeyValue>() to generate varchar(1024) Id, varchar(max) Value.

I have no issues saving objects to it. The problem is when I load the objects

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

content.Value at this point is a string.

Looking at the database record, the text for value does not appear to store any type information.

Is there really anything I can do better other than manually invoking ServiceStack.Text and call deserialize with the appropriate type information?

I do not need absolute dynamic, my actual use case is for polymorphism with a base class instead of dynamic. So I don't really care what type Value is whether it's the base class, dynamic, object, etc. Regardless other than using the class

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

I haven't been able to get anything other than a string back for Value. Can I tell OrmLite to serialize the type information to be able to correctly deserialize my objects or do I just have to do it manually?

Edit: some further information. OrmLite is using the Jsv serializer defined by ServiceStack.Text.TypeSerializer and is in no way pluggable in the BSD version. If I add a Type property to my KeyValue class with the dynamic Value I can do

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

I just really want a better way to do this, I really don't like an object of 1 type going into the db coming back out with a different type (string).

4

1 回答 1

2

我对 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);
        }
    }
}
于 2014-10-09T12:29:30.780 回答