2016-03-15 5 views
5

Ich habe Daten in einer Orakel TIMESTAMP WITH TIME ZONE Spalte gespeichert, und ich versuche jetzt, es wieder in eine Variable C# DateTimeOffset mit Dapper zu lesen. Das Problem ist, dass Dapper den Offset-Wert in der Datenbank ignoriert und meine Variable immer mit dem aktuellen Offset der Umgebung füllt.So lesen Sie Offsets von Oracle mit Dapper

Gibt es eine einfache Möglichkeit, um den Offset-Wert aus der Datenbank zu erkennen?

Grundsätzlich möchte ich etwas in dieser Richtung arbeiten sehen:

var input=new DateTimeOffset(2016, 3, 15, 14, 30, 0, TimeSpan.Zero); 
DateTimeOffset output; 
using(var connection=new OracleConnection(QueryConnectionString)) { 
    output=connection.ExecuteScalar<DateTimeOffset>("Select to_timestamp_tz('"+input.ToString("yyyy-MM-dd HH:mm zzz")+"', 'YYYY-MM-DD HH24:MI TZH:TZM') From DUAL"); 
} 
Assert.AreEqual(input, output); 

Wie geschrieben dies eine ungültige Guss Ausnahme gibt, scheint es, dass adrett liest es als Datetime und dann versucht, es zu Datetime zu werfen, zu ignorieren der Offset-Wert.

Mein Code, der eine Tabelle abfragt und ein Klassenobjekt füllt, das mit diesen Typen definiert ist, löst keinen Fehler aus, füllt aber die Objektinstanz mit dem lokalen Offset und nicht mit dem Wert in der Datenbank. So würde ich mit 2016-03-15 14:30 -5 statt 2016-03-15 14:30 +0 enden, wenn ich mit dem oben genannten Eingabewert arbeiten würde.

+0

Ich bin mir nicht sicher, dass dies ein Dapper Problem ist, sondern eher mit ODP.Net. Hilft [diese Antwort] (http://stackoverflow.com/a/14140274/634824)? –

+0

@Matt Nicht wirklich. Wenn ein Datenadapter verwendet wird, ist er in der Dapper-Implementierung eingebettet. Ich konnte keinen Zugang zu der in dieser Antwort genannten Einstellung finden. – Rozwel

+0

haben Sie versucht, 'DateTimeOffset' in utc zu konvertieren? 'output = connection.ExecuteScalar (" Wählen Sie to_timestamp_tz ('"+ input.ToUniversalTime(). ToString (" JJJJ-MM-TT HH: mm zzz ") +"', 'JJJJ-MM-TT HH24: MI TZH: TZM ') Von DUAL ");' –

Antwort

0

So bemerkte ich, dass einige andere Leute auf diese Frage gesucht haben und während ich keine direkte Antwort, ich dachte, ich würde die Arbeit teilen um das wir verwendet haben ...

Haftungsausschluss: Das ist ein bisschen ein Klud, und ich würde viel lieber einen saubereren Ansatz bevorzugen, aber es funktioniert.

Im Wesentlichen haben wir die Timestamp With Timezone-Spalte in eine formatierte Zeichenfolge in der Select-Anweisung konvertiert. In der C# -Klasse haben wir dann eine Eigenschaft hinzugefügt, bei der es sich um eine String-Repräsentation von DateTimeOffset handelt, die dasselbe Format verwendet. Wir haben dann Aliase in der Abfrage verwendet, um sicherzustellen, dass Dapper den Wert in die Zeichenfolgeneigenschaft einträgt, deren Setter sie zurück zu einem DateTimeOffset parst und die ursprüngliche Eigenschaft festlegt.