2014-01-14 88 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

明白了。謝謝你的答案。我不確定它會非常有用,但它可以。 –