C# Protobuf与实体框架数据库模型
我有EF数据库模型。 我用EF DB表类型序列化我的类包含字段。 我尝试反序列化,但字段为空C# Protobuf与实体框架数据库模型,c#,.net,entity-framework,protobuf-net,C#,.net,Entity Framework,Protobuf Net,我有EF数据库模型。 我用EF DB表类型序列化我的类包含字段。 我尝试反序列化,但字段为空 class Myclass { public EFTable table {get;set;} } 易变的 字符串str int-num [全局::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true,IsNullable=false)] [global::System.Runti
class Myclass
{
public EFTable table {get;set;}
}
易变的
- 字符串str李>
- int-num李>
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);
}
公共静态字节[]序列化(BaseInspection)
{
使用(var file=file.Create(path.ToString()))
{
序列化器。序列化(文件、检查);
}
返回文件.ReadAllBytes(path.ToString());
}
静态基线检查理想化(字节[]路径)
{
使用(流=新内存流(路径))
返回序列化程序。反序列化(流);
}
如果不能在模型下指定属性,可以使用第二种方法在应用程序启动时填充RuntimeTypeModel
。这是给我的Marc Gravell的一个样本-
电子表格的代码示例
:
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);
}
}
}
publicstaticvoidgenerate(IEnumerable类型)
{
var model=RuntimeTypeModel.Default;
foreach(类型中的变量类型)
{
int计数器=1;
var metaType=model.Add(type,false);
var properties=type.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public);
foreach(属性中的var propertyInfo)
{
添加(counter++,propertyInfo.Name);
}
}
}
和使用示例:
Generate(new List<Type>() { // list of objects that should be registered with ProtoBuf-Net
typeof(ASPStateTempSession),
typeof(ASPStateTempApplication)
});
Generate(new List(){//应该向ProtoBuf Net注册的对象列表
类型(ASPStateTempSession),
类型(ASPStateTempApplication)
});
但正如我前面所说的,如果在应用程序的新版本中添加新属性,则旧的已保存缓存数据将无法工作,因为属性的顺序将发生更改。如果类正在生成,则它们很可能是作为
部分类生成的。在这种情况下,可以在单独的代码文件中单独添加属性:
namespace YourNamespace
{
[ProtoContract]
[ProtoPartialMember(1, "table")]
partial class Myclass {}
}
这将在编译时合并,protobuf net知道如何查找ProtoPartialMember
替代表单。发布您的EFTable。EFTable的属性是否有任何Proto属性?创建EF数据库模型时,所有属性都是标准属性\SchemeProtoBuf有两种方法指定字段的顺序。第一个是在每个属性上指定属性。第二个-是在运行时创建这个RuntimeTypeModel
,并用reflectionOk填充它,我知道我没有将属性设置为EF模型,它太长了,并且我多次生成了我的db模型,这意味着我应该多次重写属性。我怎么能做得快呢?我想它会是“ppc”,我有27张桌子><谢谢你,我会努力寻找长答案。我已经添加了一个如何动态填充它们的示例谢谢,我使用自己的代码动态填充RuntimeTypeModel.Default=),但是现在我选择了BinaryBufferization,因为我也需要保存委托。。。我知道这不好。。。但现在我无法在程序中更改任何内容…嗨,Marc,我只是好奇,它会与MetadataTypeAttribute
属性一起工作吗?该属性可以与EntityFramework一起用于在单独的分部类中为域对象指定属性?我说的是这个-。如果我在MetaData类中指定Proto属性,ProtoBuf会使用它吗?@SergeyLitvinov目前还没有,但值得考虑得到它。谢谢你的回答。我不确定它是否会很有用,但它可以。