protobuf-net v2需要DataMember(Order = n)注释吗?

P a*_*u l 5 protobuf-net

简单的实验:我从Northwind创建了一个实体模型,发现生成的类在不添加Order属性的情况下不适用于protobuf-net v2 .有没有办法让实体代码生成器添加Order,或者有没有办法让protobuf-net无需工作Order

我必须改变

[DataMemberAttribute()]
Run Code Online (Sandbox Code Playgroud)

[DataMemberAttribute(Order=1)]

NorthwindEntities e = new NorthwindEntities();

using(var file = File.Create("customers.bin"))
{
    Serializer.Serialize(file, e.Customers);
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*ell 14

需要的是它有一种方法可以将成员解析为数字键.这可以采用内联属性的形式 - 例如,它允许[DataContract]/ [DataMember(Order=key)],[XmlType]/ [XmlElement(Order=key)][ProtoContract]/ [ProtoMember(key)].

也有通过选项[DataContract]推断字母合同,但这只是如果你的合同类型是安全的不会改变在未来; 要做到这一点,添加:

[ProtoContract(InferTagFromName = true)]
Run Code Online (Sandbox Code Playgroud)

到类型(可能是部分,见下文).这直接适用于您提供的场景,其中[DataMember]表示成员,但没有定义Order.我个人更喜欢显式布局,以确保稳定性.

另一种选择甚至不需要提示[DataMember]; 您可以要求它应用BinaryFormatter规则(所有字段,公共或私人)或XmlSerializer规则(公共成员,属性或字段); 但是,如果您的类型发生变化,这将非常不稳定!

[ProtoContract(ImplicitFields = ImplicitFields.AllPublic)]
Run Code Online (Sandbox Code Playgroud)

但; 另一个常见的情况是你有来自生成器的类型,你不能方便地编辑,因为任何编辑都会在重新生成时丢失; 对于那种情况,partial课程可能会有所帮助.您不能通过属性向成员添加属性,但[ProtoPartialMember]可以在此处提供帮助.例如,在单独的代码文件中:

[ProtoContract]
[ProtoPartialMember(key, memberName)]
[ProtoPartialMember(anotherKey, anotherMemberName)]
...
public partial class Order {}
Run Code Online (Sandbox Code Playgroud)

有时候,你有没有访问任何的类型,因此添加任何种类的属性是不是一种选择.如果你的场景与你描述的一样([DataContract /[DataMember] , noOrder`),那么一个懒惰的选项是全局启用它:

Serializer.GlobalOptions.InferTagFromName = true;
Run Code Online (Sandbox Code Playgroud)

或者在v2中:

RuntimeTypeModel.Default.InferTagFromNameDefault = true;
Run Code Online (Sandbox Code Playgroud)

对于更复杂的场景,v2有一个MetaType专门用于此的新模型,您可以在运行时配置布局:

RuntimeTypeModel.Default.Add(typeof(Order), false)
            .Add(key, memberName).Add(anotherKey, anotherMemberName);
Run Code Online (Sandbox Code Playgroud)

或者如果您的钥匙是1,2,3 ......那么只需:

   RuntimeTypeModel.Default.Add(typeof(Order), false)
            .Add(memberName, anotherMemberName, ...);
Run Code Online (Sandbox Code Playgroud)

(MetaType控制序列化的所有方面有很多选项)

认为这涵盖了大多数选项!