【问题标题】:Protobuf and Entity Framework DataBase ModelProtobuf 和实体框架数据库模型
【发布时间】:2014-01-14 08:51:57
【问题描述】:

我有 EF 数据库模型。 我序列化我的类,其中包含 EF DB 表类型的字段。 我尝试去实现,我有空字段的字段。

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

EFTable

  • 字符串字符串;
  • 整数;

[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")]

反序列化后 电子表格 - 字符串 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);           
}

【问题讨论】:

  • 发布您的 EFTable。 EFTable 的属性上是否有任何 Proto 属性?
  • 创建EF数据库模型\方案时都是标准的
  • ProtoBuf 有两种方式来指定字段的顺序。第一个是在每个属性上指定属性。第二个 - 是在运行时创建这个RuntimeTypeModel 并用反射填充它
  • 好吧,我知道我没有给EF模型设置属性,它太长了,我多次生成我的db模型,这意味着我要多次重写属性。我怎样才能做到快速?

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


【解决方案1】:

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

EFTable 的代码示例:

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

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

但要小心,因为 Protobuf 对属性顺序至关重要。如果你通过反射动态填充这个RuntimeTypeModel对象,然后你将添加新的属性,那么用之前版本序列化的数据将在新版本中不起作用,因为属性顺序会改变。

更新1

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

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

但正如我之前所说,如果您在新版本的应用程序中添加新属性,那么旧保存的缓存数据将不起作用,因为属性的顺序将被更改。

【讨论】:

  • 认为会是“ppc”,我有 27 张桌子 >.
  • 抱歉回答太长了。我添加了一个如何动态填充它们的示例
  • 谢谢,我使用自己的代码来动态填充 RuntimeTypeModel.Default =) 但是现在我选择了 BinaryBufferization 因为我也需要保存委托...我知道这不好...但是现在我无法更改程序中的任何内容...
【解决方案2】:

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

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

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

【讨论】:

  • 嗨,Marc,只是古玩,它是否可以与 MetadataTypeAttribute 属性一起使用,该属性可与 EntityFramework 一起使用以指定单独部分类中域对象的属性?我说的是这个 - msdn.microsoft.com/en-us/library/ee707339(v=vs.91).aspx 。如果我在 MetaData 类中指定 Proto 属性,ProtoBuf 会使用它吗?
  • @SergeyLitvinov 目前还没有,但值得考虑
  • 知道了。谢谢你的回答。我不确定它是否非常有用,但它可以。
猜你喜欢
  • 2017-10-04
  • 1970-01-01
  • 2010-10-07
  • 2011-04-28
  • 2011-04-26
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
  • 2010-09-22
相关资源
最近更新 更多