2016-10-05 8 views
2

내 응용 프로그램에서 원격 사이트의 서버에 기록 된 데이터를 보내려면 protobuf-net을 사용하고 있습니다. 여러 데이터 유형이 있습니다.이 중 하나의 샘플 메시지는 다음과 같습니다.Dapper로 프로토콜 버퍼 모델을 사용할 때 C# ticks를 PostgreSQL 타임 스탬프에 매핑하는 방법은 무엇입니까?

message Sample { 
    required int64 recording_time = 1; // UTC Timestamp in Ticks 
    required double x_position = 2; 
    required double y_position = 3; 
    required double x_velocity = 4; 
    required double y_velocity = 5; 
} 

서버에는 개체가 PostgreSQL 데이터베이스에 저장됩니다. 프로토콜 버퍼 (proto2) 메시지의 모든 double 필드는 PostgreSQL의 double 필드에 매핑됩니다. 시간 소인 필드 uint64 recording_time은 데이터베이스의 timestamp with time zone 필드에 맵핑되어야합니다.

동일한 C# 클래스 (ProtoContract 특성 사용)를 사용하여 클라이언트에서 Sample을 직렬화하고 데이터베이스 작업 (예 : FastCRUD 등)이있는 경우 Dapper를 사용하여 직렬화하려고합니다. 및 timestamp with time zone (C# 1 유형 : 날짜 시간)

ticks (긴 C# 1 형) 간의 맵핑/변환이 필요하다. 두 번째 클래스를 만들지 않고이를 구현하는 가장 좋은 방법은 무엇입니까?

이것은 내가 현재 데이터베이스 오브젝트를 작성하는 방법입니다 :

foreach (Sample sample in sampleList) 
{ 
    conn.Insert<Sample>(sample); 
} 

을 그리고 검색을 위해 해당 Query 방법을 사용하십시오

string sql = "COPY samples (recording_time, x_position, y_position, x_velocity, y_velocity) FROM STDIN (FORMAT BINARY)"; 
using (var writer = conn.BeginBinaryImport(sql)) 
{ 
    foreach (Sample sample in sampleList) 
    { 
     writer.StartRow(); 

     writer.Write(new DateTime(sample.RecordingTime, DateTimeKind.UTC), NpgsqlTypes.NpgsqlDbType.TimestampTZ); 

     writer.Write(sample.X_Position, NpgsqlTypes.NpgsqlDbType.Double); 
     writer.Write(sample.Y_Position, NpgsqlTypes.NpgsqlDbType.Double); 
     writer.Write(sample.X_Velocity, NpgsqlTypes.NpgsqlDbType.Double); 
     writer.Write(sample.Y_Velocity, NpgsqlTypes.NpgsqlDbType.Double); 

    } 
} 

이것은 내가 데이터베이스에 기록하는 방법이다.

+0

그러나 여전히 데이터베이스에 값을 저장하기 위해 C# 코드를 사용할 것입니까? 그렇다면 C# DateTime 객체를 생성하여 데이터베이스 호출에서 사용할 수 있습니다. – Evk

+0

@Evk 예, 현재 DateTime 개체를 만들고 Npgsql을 통해 데이터베이스에 쓰고 있습니다. 그러나 Dapper (또는 유사한 ORM)를 사용하여 쿼리에서 'Sample'개체를 검색하고 싶습니다. 이 변환을 Dapper 구성/초기화에 쓰는 방법이 있습니까? – Abir

답변

0

동일한 C# 클래스 (ProtoContract 특성 사용)를 사용하여 클라이언트에서 샘플을 직렬화하고 데이터베이스 작업 (예 : FastCRUD와 같은 확장명이있는 경우)을 위해 Dapper를 사용하려고합니다.

개인적으로는 동일한 문제로 두 가지 매우 다른 일을하려고하는 것이 문제라고 생각합니다. 하나! 반드시 불가능한 것은 아닙니다. 특히, protobuf-net은 개인 회원들과 행복하게 일할 것입니다. 그래서 하나의 옵션이 될 수 있습니다

public WhateverYouNeedForTheDatabase Foo { get; set; } 

[ProtoMember(someNumber)] 
private WhateverYouNeedForTheSerializer FooSerialized { 
    get { return FromX(Foo); } 
    set { Foo = ToX(value); } 
} 

당신 날씬한와 유사 할 수 있지만, 덜 편리합니다. 특히 귀하의 경우 :

public DateTime RecordingTime { get; set; } 

[ProtoMember(1)] 
private long RecordingTimeSerialized { 
    get { return DateTimeToUnixTime(RecordingTime); } 
    set { RecordingTime = UnixTimeToDateTime(value); } 
} 

추가 스토리지 요구 사항이 없습니다 (추가 필드 없음).

+0

Thanks @Marc! 나는 protobuf-net이 사적인 멤버들과 함께 작동한다는 것을 몰랐다. 제 설정으로 재검사를 할 것입니다. – Abir

+0

감사합니다. 이것으로 한 클래스로 문제가 해결됩니다. 내 응용 프로그램에는 5 가지 모델이 있습니다. _ 각 클래스에 대해 반복적 인 코드를 작성하는 것을 피할 수 있습니까? _ 시도한 한 가지 옵션은 클래스의 타임 스탬프 {public DateTime RecordingTime {get; 세트; } [ProtoMember (1)] 개인 긴 RecordingTimeSerialized {...}}''Timestamp' 객체의'RecordingTime' 속성을 해당 datebase 필드에 매핑 할 때 막혔습니다. – Abir

+0

@Arbi protobuf에서 오랫동안 DateTime을 허용하는 희망 목록 항목이 있었지만 지금까지 구현하지 않았습니다. –