Home > C# > PostgreSQL > Npgsql > ドキュメント

型のマッピング Npgsql

新規作成日 2019-02-24
最終更新日

型のマッピング

Type Mapping

サポートされている型とそれらのマッピング

Supported Types and their Mappings

以下は、CLR型をPostgreSQL型に読み書きするとき、組み込みマッピングの一覧です。

以下に加えて、列挙型と複合型のマッピングは、別のページで文書化されていることに注意してください:より多くのマッピングのサポートを追加するために、いくつかのプラグインが存在することにも注意してください。(例えば、PostGISのための空間サポート)、これらは、Typesメニューで一覧にされます。

マッピングの読み込み

Read mappings

以下は、値を読み取るとき、使用されるマッピングを示しています。

  • NpgsqlCommand.ExecuteScalar()、NpgsqlDataReader.GetValue()と類似しているメソッドを使用するとき、既定の型が、返されます。
  • NpgsqlDataReader.GetFieldValue<T>()を呼び出して、他の型として読み取ることができます。
  • プロバイダ特定の型は、NpgsqlDataReader.GetProviderSpecificValue()によって返されます。
PostgreSQL型 既定の.NET型 プロバイダ特定の型 他の.NET型
boolean bool
smallint short byte, sbyte, int, long, float, double, decimal
integer int byte, short, long, float, double, decimal
bigint long long, byte, short, int, float, double, decimal
real float double
double precision double
numeric decimal byte, short, int, long, float, double
money decimal
text string char[]
character varying string char[]
character string char[]
citext string char[]
json string char[]
jsonb string char[]
xml string char[]
point NpgsqlPoint
lseg NpgsqlLSeg
path NpgsqlPath
polygon NpgsqlPolygon
line NpgsqlLine
circle NpgsqlCircle
box NpgsqlBox
bit(1) bool BitArray
bit(n) BitArray
bit varying BitArray
hstore IDictionary<string, string>
uuid Guid
cidr ValueTuple<IPAddress, int> NpgsqlInet
inet IPAddress ValueTuple<IPAddress, int> NpgsqlInet
macaddr PhysicalAddress
tsquery NpgsqlTsQuery
tsvector NpgsqlTsVector
date DateTime NpgsqlDate
interval TimeSpan NpgsqlTimeSpan
timestamp DateTime NpgsqlDateTime
timestamp with time zone DateTime NpgsqlDateTime DateTimeOffset
time TimeSpan
time with time zone DateTimeOffset DateTimeOffset, DateTime, TimeSpan
bytea byte[]
oid uint
xid uint
cid uint
oidvector uint[]
name string char[]
(internal) char char byte, short, int, long
geometry (PostGIS) PostgisGeometry
record object[]
object[] T
range subtypes NpgsqlRange<TElement>
enum types TEnum
array types Array (of child element type)

Default .NET type列は、NpgsqlDataReader.GetValue()が、返すデータ型を指定します。

特化されていない場合、NpgsqlDataReader.GetProviderSpecificValueは、プロバイダ固有の型の列で指定されたデータ型の値や既定の.NET型を返します。

最後に、3本目の列は、PostgreSQLのデータ型のためのNpgsqlをサポートする、他のCLR型を指定します。これらは、GetFieldValue<T>()を通じて、NpgsqlDataReader.GetBoolean()、GetByte()、GetDouble()などを呼び出すことによって、取り出すことができます。

マッピングを記述する

Write mappings

パラメータに送信されるPostgreSQL型を判断する3つの規則があります。:

  1. パラメータのNpgsqlDbTypeが設定されている場合は、それが使用されます。
  2. パラメータのDataTypeが、設定されている場合、それが使用されます。
  3. パラメータのDbTypeが、設定されている場合、それが使用されます。
  4. 上記のいずれも設定されていない場合、バックエンド型は、CLR値型から推測されます。

DateTimeとNpgsqlDateTimeでは、注意して下さい。Kind属性は、timestampか、timestamptzを使うべきかどうか判断します。

NpgsqlDbType DbType PostgreSQL型 受け入れられている.NET型
Boolean Boolean boolean bool
Smallint Int16 smallint short
Integer Int32 integer int
Bigint Int64 bigint long
Real Single real float
Double Double double precision double
Numeric Decimal, VarNumeric numeric decimal
Money Currency money decimal
Text String, StringFixedLength, AnsiString, AnsiStringFixedLength text string, char[], char
Varchar character varying string, char[], char
Char character string, char[], char
Citext citext string, char[], char
Json json string, char[], char
Jsonb jsonb string, char[], char
Xml xml string, char[], char
Point point NpgsqlPoint
LSeg lseg NpgsqlLSeg
Path path NpgsqlPath
Polygon polygon NpgsqlPolygon
Circle circle NpgsqlCircle
Box box NpgsqlBox
Bit bit BitArray, bool, string
Varbit bit varying BitArray, bool, string
Hstore hstore IDictionary<string, string>
Uuid uuid Guid
Cidr cidr ValueTuple<IPAddress, int>, IPAddress, NpgsqlInet
Inet inet ValueTuple<IPAddress, int>, IPAddress, NpgsqlInet
MacAddr macaddr PhysicalAddress
TsQuery tsquery NpgsqlTsQuery
TsVector tsvector NpgsqlTsVector
Date Date date DateTime, NpgsqlDate
Interval interval TimeSpan, NpgsqlTimeSpan
Timestamp DateTime, DateTime2 timestamp DateTime, DateTimeOffset, NpgsqlDateTime
TimestampTz DateTimeOffset timestamp with time zone DateTime, DateTimeOffset, NpgsqlDateTime
Time Time time TimeSpan
TimeTz time with time zone DateTimeOffset, DateTime, TimeSpan
Bytea Binary bytea byte[], ArraySegment<byte>
Oid oid uint
Xid xid uint
Cid cid uint
Oidvector oidvector uint[]
Name name string, char[], char
InternalChar (internal) char byte
Composite composite types T
Range | (other NpgsqlDbType) range types NpgsqlRange<TElement>
Enum enum types TEnum
Array | (other NpgsqlDbType) array types Array, IList<T>, IList

子型を持つ、範囲と配列、ビットごとに、あるいは、NpgsqlDbType.RangeやNpgsqlDbType.Arrayを使用するとき、例えば、int4rangeのNpgsqlDbTypeを構築するために、NpgsqlDbType.Range | NpgsqlDbType.Integerを記述し、int[]のNpgsqlDbTypeを構築するために、NpgsqlDbType.Array| NpgsqlDbType.Integerを記述することに注意して下さい。

列挙型については、EnumsとCompositesのページを参照してください。

.NET型 自動で推測されたPostgreSQL型
bool boolean
byte smallint
sbyte smallint
short smallint
int integer
long bigint
float real
double double precision
decimal numeric
string text
char[] text
char text
NpgsqlPoint point
NpgsqlLSeg lseg
NpgsqlPath path
NpgsqlPolygon polygon
NpgsqlLine line
NpgsqlCircle circle
NpgsqlBox box
BitArray bit varying
Guid uuid
IPAddress inet
NpgsqlInet inet
PhysicalAddress macaddr
NpgsqlTsQuery tsquery
NpgsqlTsVector tsvector
NpgsqlDate date
NpgsqlDateTime timestamp
DateTime timestamp
DateTimeOffset timestamp with time zone
TimeSpan interval
byte[] bytea
Custom composite type composite types
NpgsqlRange<TElement> range types
Enum types enum types
Array types array types

日付と時刻処理

Date and Time Handling

備考:

4.0以降、日付/時刻型を扱う推奨される方法は、NodaTimeプラグインです。

通常、日付と時刻の値を扱うことは、難しいことではありませんが、あなたは、.NET型とPostgreSQLが日付をどのように表すかの違いに、注意する必要があります。PostgreSQL型に慣れるために、PostgreSQLの日付/時刻型のドキュメントを読む価値があります。

.NET型とPostgreSQL型

.NET types and PostgreSQL types

警告

よくある間違いは、ユーザーが、タイムゾーン型を持つPostgreSQLタイムスタンプが、データベースに、タイムゾーンを格納すると考えるためです。これは、そうではありません:タイムスタンプだけが、格納されます。.NET DateTimeOffsetのように、日付/時刻とタイムゾーンの両方を格納する、単一のPostgreSQL型はありません。

.NETとPostgreSQL型は、それらが提供する解像度と範囲が異なります;.NET型は、通常、PostgreSQL型に比べて、範囲が狭いですが、高い解像度を持っています。:

PostgreSQL型 精度/範囲 .NETネイティブ型 精度/範囲 Npgsql .NETプロバイダ固有の型
timestamp 1 microsecond, 4713BC-294276AD DateTime 100 nanoseconds, 1AD-9999AD NpgsqlDateTime
timestamp with timezone 1 microsecond, 4713BC-294276AD DateTime 100 nanoseconds, 1AD-9999AD NpgsqlDateTime
date 1 day, 4713BC-5874897AD DateTime 100 nanoseconds, 1AD-9999AD NpgsqlDate
time 1 microsecond, 0-24 hours TimeSpan 100 nanoseconds, -10,675,199 - 10,675,199 days N/A
time with timezone 1 microsecond, 0-24 hours DateTimeOffset (ignore date) 100 nanoseconds, 1AD-9999AD N/A
interval 1 microsecond, -178000000-178000000 years TimeSpan 100 nanoseconds, -10,675,199 - 10,675,199 days NpgsqlTimeSpan

あなたの要求が、.NETネイティブ型によって満たされる場合、あなたが、Npgsqlで、直接、それらを使用するのが最適です。しかしながら、PostgreSQL型の拡張範囲が必要な場合、あなたは、PostgreSQLの型を正確に表している、Npgsqlのプロバイダ固有の型を使うことができます。

タイムゾーン

Timezones

.NET型とPostgreSQLの間で、タイムゾーンとタイムゾーン変換が、どのように処理されるかを正確に理解することが重要です。特に、.NETのDateTimeには、Npgsqlが、値を読み書きする方法に影響する、Kindプロパティがあります。

既定では、DateTimeは、タイムゾーンなしのタイムスタンプとして、PostgreSQLに送信されます。-いかなる種類のタイムゾーン変換も行われません。そして、あなたのDateTimeインスタンスは、そのまま、PostgreSQLに転送されます。これは、データベースで、タイムスタンプを格納するために、推奨されている方法です。あなたのNpgsqlParameter上で、NpgsqlDbType.TimestampTzを設定することによって、タイムゾーンの付いたタイムスタンプとして、DateTimeを送信する場合があることに注意ください。;この場合、Kindが、ローカルである場合、Npgsqlは、値をPostgreSQLに送信する前に、UTCに変換します。それ以外の場合には、それは、現状のまま送信されます。

timestamptzとして記述され、送信前に、UTCに変換される、DateTimeOffset値を送信することもできます。

タイムゾーンを持つPostgreSQL時間は、実際に、データベースにタイムゾーンを格納する、唯一の日付/時間型です。あなたは、1つのPostgreSQLに送信する、DateTimeOffsetを使用することができます。この場合、日付コンポーネントが、削除されます。そして、時間とタイムゾーンが、保持されます。DateTimeを送信することもできます。この場合、Kindは、データベースに送信されるタイムゾーンを決定します。

詳細な動作:データベースに、値を送信する

Detailed Behavior: Sending values to the database

  
.NET値 NpgsqlDbType 動作
DateTime NpgsqlDbType.Timestamp (default) 現状のままで送信します
DateTime(Kind=UTC,Unspecified) NpgsqlDbType.TimestampTz 現状のままで送信します
DateTime(Kind=Local) NpgsqlDbType.TimestampTz ローカルに送信する前に、UTCへの変換する
DateTimeOffset NpgsqlDbType.TimestampTz (default) ローカルに送信する前に、UTCへの変換する
TimeSpan NpgsqlDbType.Time (default) 現状のままで送信します
DateTimeOffset NpgsqlDbType.TimeTz 時間とタイムゾーンを送信します
DateTime(Kind=UTC) NpgsqlDbType.TimeTz 時間とUTCタイムゾーンを送信します
DateTime(Kind=Local) NpgsqlDbType.TimeTz 時間とローカルシステム・タイムゾーンを送信します
DateTime(Kind=Unspecified) NpgsqlDbType.TimeTz ローカルを想定して、時間とローカルシステム・タイムゾーンを送信します

詳細な動作:データベースから値を読み取る

Detailed Behavior: Reading values from the database

.NET値 NpgsqlDbType 動作
timestamp DateTime (default) Kind=Unspecified
timestamptz DateTime (default) Kind=Local(システムタイムゾーンに従う)
timestamptz DateTimeOffset オフセットされるローカル・タイムゾーンで
time TimeSpan (default) 現状のまま
timetz DateTimeOffset (default) 日付のコンポーネントは空です
timetz TimeSpan ストリップ・オフセット、現状のまま読み取る
timetz DateTime ストリップオフセット、日付は空です

さらに読む

Further Reading

あなたが、上記のマッピングの決定のいくつかに、本当に興味を持っている場合、この問題を確認して下さい。

PostgreSQLの列挙型と複合型

PostgreSQL enums and composites

PostgreSQLは、データベースの列として、列挙型複合型をサポートしています。そして、Npgsqlは、これらの読み書きをサポートします。これにより、変換を気にせずに、データベースに対して、列挙と複合値をシームレスに、読み書きできます。

あなたのCLR型をマッピングする

Mapping your CLR types

列挙型と複合型を扱うための推奨方法は、あなたのCLR型のマッピングを設定することです。それを行うことは、次の利点を提供します。:

すべての接続に適用される、グローバル・マッピングを設定するために、最初の接続が、開かれる前に、このコードを配置します。:

NpgsqlConnection.GlobalTypeMapper.MapEnum<SomeEnum>("some_enum_type");
NpgsqlConnection.GlobalTypeMapper.MapComposite<SomeType>("some_composite_type");

これは、PostgreSQL型のsome_enum_typeとsome_composite_typeに、あなたのCLR型のSomeEnumとSomeTypeの間で、マッピングを設定します。

あなたが、すべての接続のためのマッピングを設定したくない場合、あなたは、1つだけ接続を設定できます。:

var conn = new NpgsqlConnection(...);
conn.TypeMapper.MapEnum<SomeEnum>("some_enum_type");
conn.TypeMapper.MapComposite<SomeType>("some_composite_type");

マッピングの後、あなたは、いつものように、あなたのCLR型を読み書きすることができます。:

// Writing
using (var cmd = new NpgsqlCommand("INSERT INTO some_table (some_enum_column, some_composite_column) VALUES (@p1, @p2)", conn))
{
    cmd.Parameters.Add(new NpgsqlParameter
    {
        ParameterName = "p1",
        Value = SomeEnum.Good
    });
    cmd.Parameters.Add(new NpgsqlParameter
    {
        ParameterName = "p2",
        Value = new SomeType { ... }
    });
    cmd.ExecuteNonQuery();
}

// Reading
using (var cmd = new NpgsqlCommand("SELECT some_enum_column, some_composite_column FROM some_table", conn))
using (var reader = cmd.ExecuteReader()) {
    reader.Read();
    var enumValue = reader.GetFieldValue<SomeEnum>(0);
    var compositeValue = reader.GetFieldValue<SomeType>(1);
}

あなたのPostgreSQLの列挙型と複合型(上のサンプルのsome_enum_typeとsome_composite_type)に、最初の接続が作成される前に、あなたのデータベースで、定義する必要があることに注意してください(CREATE TYPEを参照)。あなたのプログラムで、PostgreSQL型を作成している場合、Npgsqlが、それらを正しく認識するようにするには、NpgsqlConnection.ReloadTypes()を呼び出します。

名前変換

Name Translation

CLR型とフィールド名は、通常、(例えば、SomeType)camel caseです。一方、PostgreSQLでは、(例えば、some_type)snake caseです。列挙型と複合型のマッピングを継ぎ目がないようにするために、プラグイン可能な名前変換プログラムは、すべての名前を変換するために使用されます。SomeTypeのような、名前をsome_typeにマッピングする、省略時設定の変換スキームはNpgsqlSnakeCaseNameTranslatorになりますが、あなたは、othersを指定することができます。既定の名前トランスレータは、NpgsqlConnection.GlobalTypeMapper.DefaultNameTranslator、あるいは、NpgsqlConnection.TypeMapper.DefaultNameTranslatorのための特定の接続を通して、あなたのすべての接続のために設定することができます。マッピングを設定するとき、あなたは、名前トランスレータを指定することもできます。:

NpgsqlConnection.GlobalTypeMapper.MapComposite<SomeType>("some_type", new NpgsqlNullNameTranslator());

最後に、あなたは、[PgName]属性を使用して、フィールドごとにマッピングを制御できます。これは、名前トランスレータを上書きするでしょう。

using NpgsqlTypes;

enum SomeEnum {
   [PgName("happy")]
   Good,
   [PgName("sad")]
   Bad
}

(CLR型なしで)動的に読み書きする

Reading and Writing Dynamically (without CLR types)

いくつかの場合では、既存のCLR型なしで、PostgreSQLの列挙型と複合型と対話することが、望ましい場合があります。-これは、主に役に立ちます。あなたのプログラムが、前もって、データベースのスキーマと型を知らない場合、そして、どんな列挙型/複合型とも対話する必要があります。CLR型を使用する方が、安全で速いことに注意してください。(複合型のための)、そして、可能であれば優先すべきです。

列挙型は、単純な文字列として、読み書きすることができます。:

// Writing enum as string
using (var cmd = new NpgsqlCommand("INSERT INTO some_table (some_enum_column) VALUES (@p1)", conn))
{
    cmd.Parameters.Add(new NpgsqlParameter
    {
        ParameterName = "p1",
        Value = "Good"
        DataTypeName = "some_enum_type"
    });
    cmd.ExecuteNonQuery();
}

// Reading enum as string
using (var cmd = new NpgsqlCommand("SELECT some_enum_column FROM some_table", conn))
using (var reader = cmd.ExecuteReader()) {
    reader.Read();
    var enumValue = reader.GetFieldValue<string>(0);
}

複合型は、C#の動的なExpandoObjectsとして、読み書きすることができます。:

// Writing composite as ExpandoObject
using (var cmd = new NpgsqlCommand("INSERT INTO some_table (some_composite_column) VALUES (@p1)", Conn))
{
    var someComposite = new ExpandoObject();
    some_composite.Foo = 8;
    some_composite.Bar = "hello";
    cmd.Parameters.Add(new NpgsqlParameter
    {
        ParameterName = "p1",
        Value = someComposite,
        DataTypeName = "some_composite_type"
    });
    cmd.ExecuteNonQuery();
}

// Reading composite as ExpandoObject
using (var cmd = new NpgsqlCommand("SELECT some_composite_column FROM some_table", conn))
using (var reader = cmd.ExecuteReader()) {
    reader.Read();
    var compositeValue = (dynamic)reader.GetValue(0);
    Console.WriteLine(compositeValue.Foo);
    Console.WriteLine(compositeValue.Bar);
}

あなたのCLR型のSomeEnumとSomeTypeが、フィールド/プロパティが含まれている限り、読み書きされるPostgreSQL型に対応し、すべてが、期待通りに動作します。既定の名前トランスレータが、使用されることに注意してください。(名前変換についての項目を参照して下さい)。

NodaTime型プラグイン

NodaTime Type Plugin

4.0以降、Npgsqlは、Npgsqlが、PostgreSQL値のCLR型へのマッピングを、どのように変更するか、外部nugetパッケージの型プラグインをサポートしています。これらの1つは、NodaTimeプラグインです。それは、Npgsqlが、NodaTime型を読み書きするようにします。NodaTimeプラグインは、現在、PostgreSQLの日付/時刻型と対話するための推奨された方法です。そして、NodaTimeライブラリへの依存関係が追加されたため、デフォルトではありません。

NodaTimeとは、何ですか?

What is NodaTime?

既定では、PostgreSQLの日付/時刻型は、組み込み.NET型(DateTime、TimeSpan)にマッピングされています。残念ながら、これらの組込み型は、多くの欠点があります。NodaTimeライブラリは、これらの多くの問題を解決するために作成されました。そして、あなたのアプリケーションが、最も基本的な方法以外の何かで、日付と時刻を処理する場合、あなたは、それを使用することを考える必要があります。詳しくは、Jon Skeetによるこのブログ記事を読んでください。

NodaTimeの一般的な利点を越えて、NodaTime for PostgreSQLの日付/時刻マッピングには、次のような特別な利点があります。:

  • NodaTimeは、LocalDate、LocalTimeとOffsetTimeのような、BCLから欠落して、いくつかの型を定義します。これらは、PostgreSQLのdate、time、およびtimetzに完全に一致しています。
  • 期間は、TimeSpanよりも、PostgreSQLの間隔のマッピングに適しています。
  • NodaTime型は、PostgreSQLのマイクロ秒精度を完全に表すことができます。そして、BCLの日付制限(1AD-9999AD)の範囲外の日付を表すことができます。

設定

Setup

NodaTimeプラグインを使用するために、単純に、Npgsql.NodaTimeへの依存関係を追加して設定するだけです。:

using Npgsql;

// Place this at the beginning of your program to use NodaTime everywhere
 (recommended)
// NodaTime everywhere(推奨)を使うために、あなたのプログラムの始めに、これを置いてください。
NpgsqlConnection.GlobalTypeMapper.UseNodaTime();

// Or to temporarily use NodaTime on a single connection only:
// あるいは、単一の接続でのみで、NodaTimeを一時的に使用するには:
conn.TypeMapper.UseNodaTime();

値の読み書き

Reading and Writing Values

一旦、プラグインが設定されると、あなたは、NodaTimeオブジェクトを透過的に読み書きできます。:

// Write NodaTime Instant to PostgreSQL "timestamp without time zone"
// NodaTime InstantをPostgreSQLに、"timestamp without time zone"を書き込みます。
using (var cmd = new NpgsqlCommand(@"INSERT INTO mytable (my_timestamp) VALUES (@p)", conn))
{
    cmd.Parameters.Add(new NpgsqlParameter("p", Instant.FromUtc(2011, 1, 1, 10, 30)));
    cmd.ExecuteNonQuery();
}

// Read timestamp back from the database as an Instant
// Instantとして、データベースからタイムスタンプを読み戻します。
using (var cmd = new NpgsqlCommand(@"SELECT my_timestamp FROM mytable", conn))
using (var reader = cmd.ExecuteReader())
{
    reader.Read();
    var instant = reader.GetFieldValue(0);
}

マッピング・テーブル

Mapping Table

警告

よくある間違いは、ユーザーが、タイムゾーン型を持つPostgreSQLタイムスタンプが、データベースに、タイムゾーンを格納すると考えるためです。これは、そうではありません:タイムスタンプだけが、格納されます。日付/時刻とタイムゾーンの両方を格納する、単一のPostgreSQL型はありません。.NET DateTimeOffsetに似ています。

PostgreSQL型 既定のNodaTime型 追加のNodaTime型 備考
timestamp Instant LocalDateTime それは、データベースに、UTCタイムスタンプを格納するのが一般的です。-あなたは、単純に、行うことができ、Instant値を読み書きすることができます。あなたは、LocalDateTimeを読み書きのオプションも持っています。それは、タイムゾーンに関する情報のない日付/時間です。;これは、理にかないます。あなたが、タイムゾーンを異なる列に格納している場合、そして、NodaTimeとZonedDateTimeの両方を読み込むことをお勧めします。
time zoneを持つtimestamp Instant ZonedDateTime, OffsetDateTime このPostgreSQL型は、UTCであると仮定したタイムスタンプだけを格納しています。あなたが、これをInstantとして読み書きする場合、タイムゾーン変換なしで、格納された状態で提供されます。しかしながら、ZonedDateTimeやOffsetDateTimeとして読み書きする場合、プラグインは、あなたのPostgreSQLセッションのタイムゾーンに従って、自動的に、UTCとの間で変換します。
date LocalDate タイムゾーンやオフセット情報を持たない単純な日付。
time LocalTime タイムゾーンやオフセット情報を持たない単純な時刻。
time zone を持つtime OffsetTime これは、時間とオフセットを格納するPostgreSQL型です。
interval Period これは、固定された絶対長("two months"は、問題の月によって異なります)を持っていない、人間の間隔です。そして、そのため、それは、NodaTimeのPeriod(そして、DurationやTimeSpanではありません)にマッピングされます。

その他のメモ

Additional Notes

  • プラグインは、自動的に、あなたのPostgreSQLセッションの設定されたタイムゾーンとの間で、タイムゾーン付きのタイムスタンプを変換します。;これは、代わりに、あなたのマシンのローカル・タイムゾーンを使用する、Npgsqlの既定のマッピングと異なります。timestamptz値と対話するとき、NodaTimeプラグイン動作は、標準のPostgreSQL動作と一致します。
  • タイムスタンプや日付の無限値を読み書きするために、Convert Infinity DateTime接続文字列パラメーターをtrueに設定し、MaxValue / MinValueを読み書きします。

Json.NET型のプラグイン

Json.NET Type Plugin

4.0以降、Npgsqlは、型プラグインをサポートしています。これは、外部nugetパッケージです。Npgsqlが、PostgreSQL値のCLR型へのマッピングを、どのように変更するか、これらの1つは、JSONデータを読み書きするとき、Npgsqlが、自動的に、Newtonsoft Json.NETを使用できる、Json.NETプラグインです。

PostgreSQLは、ネイティブで、2つのJSON型をサポートしています。:jsonbとjson。すぐに使える、Npgsqlは、文字列として、これらの型を読み書きすることができます。そして、Npgsqlユーザーに、JSON値自体をシリアライズやデシリアライズすることを強制する外部のJSONライブラリに、依存しないようにするための追加の処理を提供していません。Json.NETプラグインは、Npgsql自身の中で、シリアル化/逆シリアル化を実行することで、この負担をユーザーから取り除きます。

設定

Setup

Json.NETプラグインを使用するために、単純に、Npgsql.Json.NETへの依存関係を追加し、設定するだけです。:

using Npgsql;

// Place this at the beginning of your program to use Json.NET everywhere (recommended)
// どこでもJson.NETを使う(推奨)ために、あなたのプログラムの先頭に、これを配置します。
NpgsqlConnection.GlobalTypeMapper.UseJsonNet();

// Or to temporarily use JsonNet on a single connection only:
// あるいは、単一の接続でのみで、JsonNetを一時的に使用するには:
conn.TypeMapper.UseJsonNet();

任意のCLR型

Arbitrary CLR Types

一旦、プラグインが設定されると、あなたは、JSON値として、透過的に、CLRオブジェクトを読み書きすることができます。-プラグインは、自動的に、それらをシリアル化/逆シリアル化します。:

// Write arbitrary CLR types as JSON
// 任意のCLR型を、JSONとして記述します。
using (var cmd = new NpgsqlCommand(@"INSERT INTO mytable (my_json_column) VALUES (@p)", conn))
{
    cmd.Parameters.Add(new NpgsqlParameter("p", NpgsqlDbType.Jsonb) { Value = MyClrType });
    cmd.ExecuteNonQuery();
}

// Read arbitrary CLR types as JSON
// 任意のCLR型を、JSONとして読み込みます
using (var cmd = new NpgsqlCommand(@"SELECT my_json_column FROM mytable", conn))
using (var reader = cmd.ExecuteReader())
{
    reader.Read();
    var someValue = reader.GetFieldValue(0);
}

上の例では、Npgsqlに、パラメータ型が、JSONであることを伝えるために、あなたが、依然として、NpgsqlDbType.Json(あるいは、Jsonb)を指定する必要があることに注意して下さい。あなたが、いくつかのCLR型を使用している場合、あなたは、JSONに、それらをマッピングするオプションを持っています。:

NpgsqlConnection.GlobalTypeMapper.UseJsonNet(new[] { typeof(MyClrType) });

UseJsonNet()メソッドが、2つの型配列(arrays)を受け取ることに注意して下さい。:1つ目は、jsonbにマッピングする型のために、2つ目は、jsonにマッピングする型のために。

JObject/JArray

あなたは、直接、Json.NETのJObject/JArray型を読み書きすることもできます。:

var value = new JObject { ["Foo"] = 8 };
using (var cmd = new NpgsqlCommand(@"INSERT INTO mytable (my_json_column) VALUES (@p)", conn))
{
    cmd.Parameters.Add(new NpgsqlParameter("p", NpgsqlDbType.Jsonb) { Value = value });
    cmd.ExecuteNonQuery();
}

using (var cmd = new NpgsqlCommand(@"SELECT my_json_column FROM mytable", conn))
using (var reader = cmd.ExecuteReader())
{
    reader.Read();
    var someValue = reader.GetFieldValue(0);
}

CLR配列(arrays)

CLR Arrays

あなたは、JSONとして、ネイティブCLR配列を読み書きすることもできます。:

using (var cmd = new NpgsqlCommand(@"INSERT INTO mytable (my_json_column) VALUES (@p)", conn))
{
    cmd.Parameters.Add(new NpgsqlParameter("p", NpgsqlDbType.Jsonb) { Value = new[] { 1, 2, 3} });
    cmd.ExecuteNonQuery();
}

using (var cmd = new NpgsqlCommand(@"SELECT my_json_column FROM mytable", conn))
using (var reader = cmd.ExecuteReader())
{
    reader.Read();
    var someValue = reader.GetFieldValue<int[]>(0);
}

そして、追加のクレジット型のため、同様に、配列型のために、通常のCLRタイプのために、あなたは、デフォルトで、JSONを指定することができます。:

NpgsqlConnection.GlobalTypeMapper.UseJsonNet(new[] { typeof(int[]) });

これは、デフォルトで、Npgsqlが、JSONとして、int配列(arrays)を送信するようにする(PostgreSQL配列(arrays)を送信する)、既定の配列マッピングを上書きします。

このエントリーをはてなブックマークに追加

Home PC C# Illustration

Copyright (C) 2011 Horio Kazuhiko(kukekko) All Rights Reserved.
kukekko@gmail.com
ご連絡の際は、お問い合わせページのURLの明記をお願いします。
「掲載内容は私自身の見解であり、所属する組織を代表するものではありません。」