Protobuf和实体框架数据库模型

时间:2014-01-14 08:51:58

标签: c# .net entity-framework protobuf-net

我有EF databaseModel。 我序列化我的类包含EF DB表类型的字段。 我尝试deserealize,我有空字段的字段。

class Myclass
{
    public EFTable table {get;set;}
}

EFTable

  • string str;
  • int num;

[global :: System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty = true,IsNullable = false)] [global :: System.Runtime.Serialization.DataMemberAttribute()] [global :: System.CodeDom.Compiler.GeneratedCode(“System.Data.Entity.Design.EntityClassGenerator”,“4.0.0.0”)]

反序列化后 EFTable - string str = null - int num = 0

为什么呢?如何修复它而不创建临时类?

public static byte[] Serialize(BaseInspection inspection)
{
    using (var file = File.Create(path.ToString()))
    {
        Serializer.Serialize(file, inspection);
    }
    return File.ReadAllBytes(path.ToString());
}

static BaseInspection Desirialize(byte[] path)
{

    using (Stream stream = new MemoryStream(path))
        return Serializer.Deserialize<BaseInspection>(stream);           
}

2 个答案:

答案 0 :(得分:1)

如果您无法在模型下指定属性,则可以使用第二种方法在应用程序启动时填充RuntimeTypeModel。以下是Marc Gravell给出的样本 - Protobuf-net serialization without annotation

EFTable的代码示例:

RuntimeTypeModel.Default.Add(typeof(EFTable), false).Add("str", "num",);

或者您可以根据您的EFTable属性填充反射,然后它应该正确序列化。

但要注意,因为Protobuf对物业订单至关重要。如果您通过反射动态填充此RuntimeTypeModel对象,然后您将添加新属性,那么使用以前版本序列化的数据将无法在新版本中工作,因为属性顺序将会更改。

<强> UPDATE1

正如我所提到的,您也可以使用反射来动态填充字段。以下是此类方法的示例:

public static void Generate(IEnumerable<Type> types)
{
    var model = RuntimeTypeModel.Default;

    foreach (var type in types)
    {
        int counter = 1;
        var metaType = model.Add(type, false);

        var properties = type.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public);
        foreach (var propertyInfo in properties)
        {
            metaType.Add(counter++, propertyInfo.Name);
        }

    }
}   

使用示例:

Generate(new List<Type>() { // list of objects that should be registered with ProtoBuf-Net
    typeof(ASPStateTempSession),  
    typeof(ASPStateTempApplication) 
});

但正如我之前所说,如果你在新版本的应用程序中添加新属性,那么旧的已保存缓存数据将无效,因为属性顺序将会改变。

答案 1 :(得分:1)

如果正在生成类,则很可能将它们生成为partial类。在这种情况下,您可以在单独的代码文件中单独添加属性:

namespace YourNamespace
{
    [ProtoContract]
    [ProtoPartialMember(1, "table")]
    partial class Myclass {}
}

这将在编译时合并,protobuf-net知道寻找ProtoPartialMember替代形式。