2014-01-14 59 views
0

我有EF databaseModel。 我使用EF DB Table Type序列化我的类包含字段。 我试图去实现,我有与空领域的领域。Protobuf和实体框架数据库模型

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

EFTable

  • 字符串str;
  • int num;

[全球:: System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty =真,ISNULLABLE =假)] [全球:: System.Runtime.Serialization.DataMemberAttribute()] [全球::系统。 CodeDom.Compiler.GeneratedCode( “System.Data.Entity.Design.EntityClassGenerator”, “4.0.0.0”)]

后反序列化 EFTable - 字符串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);   
} 
+0

发布您的EFTable。 EFTable的属性是否有任何Proto属性? –

+0

当创建EF数据库模型\ Scheme – Risa

+0

时,所有的都是标准的。ProtoBuf有两种方式来指定字段的顺序。首先是在每个属性上指定属性。第二个 - 在运行时创建这个'RuntimeTypeModel',并用反射填充 –

回答

1

如果您不能指定模型下的属性,你可以用第二种方法去在应用程序启动,以填补RuntimeTypeModel。这是给我的马克Gravell的样本 - 为您EFTableProtobuf-net serialization without annotation

代码示例:

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

或者,您可以根据您的EFTable性反射填补它,那么它应该正确地序列。

但要小心,因为Protobuf对属性顺序至关重要。如果您通过反射动态填充此对象,然后您将添加新属性,那么与先前版本序列化的数据不会在新版本中运行,因为属性顺序将发生更改。

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) 
}); 

但正如我以前说过,如果你在你的应用程序的新版本中增加新的属性,那么旧保存的缓存数据赢得没有用,因为房产的顺序将会改变。

+0

认为它会是“ppc”,我有27个表格。“<谢谢,将尝试 – Risa

+0

对不起,长时间回答。我已经添加了一个示例如何动态填充它们 –

+0

谢谢,我用我自己的代码来动态填充RuntimeTypeModel.Default =)但是现在我选择了BinaryBufferization,因为我也需要保存委托...我知道这不好。 ..但现在我不能改变任何程序... – Risa

1

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

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

这将在编译时被合并,protobuf网知道如何寻找的ProtoPartialMember替代形式。

+0

嗨马克,只是好奇心,它可以与'MetadataTypeAttribute'属性,可以与EntityFramework一起使用指定在单独的部分类中的域对象的属性?我正在谈论这个 - http://msdn.microsoft.com/en-us/library/ee707339(v=vs.91).aspx。如果我在MetaData类中指定Proto属性,ProtoBuf会使用它吗? –

+1

@SergeyLitvinov不在目前,但它是值得考虑的东西 –

+0

明白了。谢谢你的答案。我不确定它会非常有用,但它可以。 –