2014-01-14 3 views
0

EF databaseModel 있습니다. 나는 나의 클래스를 직렬화한다 thet에는 EF DB 테이블 유형을 가진 분야가있다. 나는 deserealize하려고하고 null 필드가있는 필드가 있습니다.Protobuf 및 Entity Framework 데이터베이스 모델

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

EFTable

  • 문자열 str을;
  • int num;

[글로벌 :: System.Data.Objects.DataClasses.EdmScalarPropertyAttribute (EntityKeyProperty = TRUE, 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 DataBase Model \ Scheme을 만들 때 모든 것은 표준입니다. – Risa

+0

ProtoBuf에는 필드 순서를 지정하는 두 가지 방법이 있습니다. 첫 번째는 각 속성에 속성을 지정하는 것입니다. 두 번째 것 - 런타임에이 RuntimeTypeModel을 생성하여 리플렉션으로 채우는 것입니다. –

답변

1

, 당신은 응용 프로그램 시작시 RuntimeTypeModel을 채우기 위해 두 번째 방법으로 갈 수 있습니다.

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

또는 당신은 당신의 EFTable 속성을 기반으로 반사와 함께 그것을 채울 수 있고, 그때는 제대로 직렬화한다 : 당신의 EFTable에 대한 Protobuf-net serialization without annotation

코드 샘플 - 여기 내 마크 Gravell 주어진 샘플입니다.

하지만 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) 
}); 

는하지만, 다음, 오래된 데이터가 원 캐쉬 시간 저장 재산의 순서가 바뀔 것이므로 일하지 마라.

+0

그것이 "ppc"가 될 것이라고 생각합니다, 나는 27 개의 테이블을 가지고 있습니다. <감사합니다. – Risa

+0

죄송합니다. 동적으로 채우는 방법을 샘플을 추가했습니다. –

+0

감사합니다. 동적으로 채우기 위해 내 자신의 코드를 사용했습니다. RuntimeTypeModel.Default =) 그러나 이제는 BerryBufferization을 선택했는데, 위임자를 저장해야하기 때문에 ... 좋지 않습니다. ..하지만 지금은 programm에서 아무것도 변경할 수 없습니다 ... – Risa

1

클래스가 생성되는 경우 클래스가 partial 클래스로 생성 될 가능성이 큽니다. 이 경우에, 당신은 별도의 코드 파일에서 개별적으로 속성을 추가 할 수 있습니다

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

이 컴파일시에 합병 및 protobuf-NET은 ProtoPartialMember 다른 형태를 찾기 위해 알고됩니다.

+0

안녕하세요 마크, 그냥 골동품, EntityFramework 함께 별도의 부분 클래스의 도메인 개체에 대한 속성을 지정하는 데 사용할 수있는'MetadataTypeAttribute' 속성과 함께 작동합니까? 나는 이것에 대해 이야기하고있다. - http://msdn.microsoft.com/en-us/library/ee707339(v=vs.91).aspx. Proto 속성을 MetaData 클래스에 지정하면 ProtoBuf가 그것을 사용합니까? –

+1

@SergeyLitvinov는 현재 시간이 아니지만 고려해야 할 가치가 있습니다. –

+0

알겠습니다. 답변 감사합니다. 나는 그것이 매우 유용 할 것이라는 확신이 없지만 그렇게 할 수는있다. –