プライマリ・コンテンツに移動

Oracle® Data Provider for .NET開発者ガイド ODAC 12.2c リリース1 (12.2.0.1) for Microsoft Windows E88311-03 |
| 目次 | 索引

前 | 次 |

# Oracle Numberデータ型のデフォルト・マッピングおよびカスタマイズ

この項では、デフォルトの数値マッピング動作と、アプリケーションのためにそれをカスタマイズする方法について説明します。.NET構成ファイルでカスタム・マッピングを構成して、整数値を表すOracleの各`Number(p,0)`のデフォルト・マッピングを上書きできます。

整数を表すOracle `NUMBER`データ型には、正確に同じ範囲で許容される値を持つ、一致する.NET整数データ型がありません。ODP.NETは、カスタムのデータ型マッピングを必要とせずに.NETの整数型値をOracleデータベースに格納できる、デフォルトのマッピングを使用します。ただし、データベースから値を取得するとき、Oracleの`NUMBER(p,0)`列データは、.NETデータ型で保持できるより大きくなる場合があります。

たとえばEntity Framework 6では、Oracleの`NUMBER(3,0)`はデフォルトでNET Byteにマッピングされます。Oracleの`NUMBER(3,0)`には最大`999`までの値を格納でき、.NETの`BYTE`には最大`255`までの値を格納できます。Oracleのデータが`255`を超えると想定される場合は、マッピングをより大きい数値データ型、たとえば.NETの`Int16`に変更してください。このようにカスタム・マッピングを設定すると、エラーを発生させずに、.NETでデータを使用できます。このようなカスタム・マッピングを使用するときには、Oracleの`NUMBER(3,0)`が保持できる制限を超えて.NETの`Int16`を挿入しないよう注意してください。`Int16.MaxValue` (すなわち`32,767`)を`NUMBER(3,0)`列に挿入すると、Oracle Databaseエラーが発生します。

## Entity Framework 5および早期マッピングおよびカスタマイズ

例4-1に、カスタム・マッピングを使用して`Number(1,0)` Oracleデータ型を`bool` EDM型にマップするODP.NET管理対象外ドライバ`app.config`ファイルのサンプルを示します。たとえば、デフォルトで`Int16`にマップされている`Number(1,0)`を、カスタムで.NET `Bool`型または.NET `Byte`型にマップできます。この例では、`Number(3,0)`をbyteにマップし、`Int16`、`Int32`および`Int64`データ型の最大精度をそれぞれ`4`、`9`および`18`に設定します。

例4-2は例4-1と同じ変更を示しますが、従来のODP.NET管理対象外ドライバ`app.config`形式を使用します。

例4-3に、ODP.NET管理対象ドライバのサンプル`app.config`ファイルを示します。

例4-1、例4-2および例4-3では、マッピングを次のようにカスタマイズしています。

Oracleタイプ | デフォルトのEDM型 | カスタムのEDM型
--- | --- | ---
`Number(1,0)` | `Int16` | `bool`
`Number(2,0)`から`Number(3,0)` | `Int16` | `byte`
`Number(4,0)` | `Int16` | `Int16`
`Number(5,0)` | `Int16` | `Int32`
`Number(6,0)`から`Number(9,0)` | `Int32` | `Int32`
`Number(10,0)` | `Int32` | `Int64`
`Number(11,0)`から`Number(18,0)` | `Int64` | `Int64`
`Number(19,0)` | `Int64` | `Decimal`

カスタム・マッピングによって、.NET/EDM型にマップされるOracle `Number`型の最大精度が構成されます。このため、たとえば、前述のカスタム・アプリケーション構成ファイルでODP.NETを構成する際は、`Int64`にデフォルトの範囲である`Number(11,0)` から`Number(19,0)`ではなく、`Int64`に`Number(10,0)`から`Number(18,0)`をマップするよう構成されます。

注意:

- カスタム・マッピングでは、すべての.NET/EDM型をマップする必要はありません。たとえば、`Int16`についてのみカスタム・マッピングが必要な場合は、`Int16`の単一のエントリで行うことができます。他の型には、デフォルト・マッピングが使用されます。

- Model Firstを使用している場合は、デフォルトで`Number(3,0)`に`Byte`属性がマップされます。ただし、`Number(3,0)`列にモデルが生成されている場合は、`Byte`にカスタム・マッピングを指定しないかぎり、デフォルトで`Int16`にマップされます。

マッピングによってデータが.NET/EDM型および`Number(p, s)` 型の範囲内に適合することを確認する必要があります。Oracle `Number`データに対して範囲が小さすぎる.NET/EDM型を選択した場合、データの取得時にエラーが発生します。また、.NET/EDM型を選択した場合に、対応するデータがOracle `Number`列に対して大きすぎると、Oracle DatabaseにINSERTおよびUPDATEを行った際にエラーが発生します。

例4-1 Number (p,0)データ型をカスタム・マップするODP.NET管理対象外ドライバのアプリケーション構成ファイルの最初のサンプル

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <oracle.unmanageddataaccess.client>
        <version number="*">
           <edmMappings>
               <edmMapping dataType="number">
                   <add name="bool" precision="1"/>
                   <add name="byte" precision="3" />
                   <add name="int16" precision="4" />
                   <add name="int32" precision="9" />
                   <add name="int64" precision="18" />
              </edmMapping>
           </edmMappings>
         </version>
      </oracle.unmanageddataaccess.client>
    </configuration>

例4-2 Number (p,0)データ型をカスタム・マップするODP.NET管理対象外ドライバのアプリケーション構成ファイルの2番目のサンプル

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <connectionStrings>
      </connectionStrings>
      <oracle.dataaccess.client>
        <settings>
          <add name="bool" value="edmmapping number(1,0)" />
          <add name="byte" value="edmmapping number(3,0)" />
          <add name="int16" value="edmmapping number(4,0)" />
          <add name="int32" value="edmmapping number(9,0)" />
          <add name="int64" value="edmmapping number(18,0)" />
        </settings>
      </oracle.dataaccess.client>
    </configuration>

例4-3 Numberデータ型をカスタム・マップするODP.NET管理対象ドライバのアプリケーション構成ファイルのサンプル

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <oracle.manageddataaccess.client>
        <version number="*">
           <edmMappings>
               <edmMapping dataType="number">
                   <add name="bool" precision="1"/>
                   <add name="byte" precision="3" />
                   <add name="int16" precision="4" />
                   <add name="int32" precision="9" />
                   <add name="int64" precision="18" />
              </edmMapping>
           </edmMappings>
         </version>
      </oracle.manageddataaccess.client>
    </configuration>

## Entity Framework 6マッピングおよびカスタマイズ

ODP.NET 12.1.0.2では、管理対象および管理対象外の両方のODP.NETに新しい.NET構成設定形式を導入しました。この新しい設定形式は、Entity Framework 6およびEntity Data Modelマッピングとの使用にのみ適用されます(Code First、Database FirstおよびModel Firstユースケースを含む)。開発者は、Entity Framework 6以外のアプリケーションで既存のODP.NET形式を使用し続けられます。

この新しい形式は、ODP.NET管理対象ドライバおよび管理対象外ドライバがそれぞれの構成値を設定する方法を統一し、自動実行をサポートします。

次に、ODP.NET管理対象ドライバの`edmMappings`セクションの例を示します。

    <oracle.manageddataaccess.client>
      <version number="*">
        <edmMappings>
          <edmNumberMapping>
            <add NETType="bool" MinPrecision="1" MaxPrecision="1" DBType="Number" />
            <add NETType="byte" MinPrecision="2" MaxPrecision="3" DBType="Number" />
            <add NETType="int16" MinPrecision="4" MaxPrecision="5" DBType="Number" />
            <add NETType="int32" MinPrecision="6" MaxPrecision="10" DBType="Number" />
            <add NETType="int64" MinPrecision="11" MaxPrecision="19" DBType="Number" />
          </edmNumberMapping>
        </edmMappings>
      </version>
    </oracle.manageddataaccess.client>

ここで

- `DBType`はOracle Databaseデータ型です

- `NETType`は、Oracleデータ型がマップされる.NETデータ型です

- `MinPrecision`は、Oracleデータ型が.NET型にマップされる最小範囲です

- `MaxPrecision`は、Oracleデータ型が.NET型にマップされる最大範囲です

次に、ODP.NET管理対象外ドライバの`edmmappings`セクションの例を示します。開始タグと終了タグ以外は、管理対象ドライバと完全に同じ形式です。

    <oracle.unmanageddataaccess.client>
      <version number="*">
        <edmMappings>
          <edmNumberMapping>
            <add NETType="bool" MinPrecision="1" MaxPrecision="1" DBType="Number" />
            <add NETType="byte" MinPrecision="2" MaxPrecision="3" DBType="Number" />
            <add NETType="int16" MinPrecision="4" MaxPrecision="5" DBType="Number" />
            <add NETType="int32" MinPrecision="6" MaxPrecision="10" DBType="Number" />
            <add NETType="int64" MinPrecision="11" MaxPrecision="19" DBType="Number" />
          </edmNumberMapping>
        </edmMappings>
      </version>
    </oracle.unmanageddataaccess.client>

### 新しいデフォルト・マッピング

Entity Framework 6では、ODP.NET 12.1.0.2は、Code First、Database FirstおよびModel Firstのシナリオに適用される新しいデフォルト・マッピングを導入しました。Code First互換性をサポートするためには、次の変更が必要でした。

- デフォルトで、.NET `Booleans`はOracle `Number(1,0)`にマップされ、逆にもマップされます

- デフォルトで、.NET `Bytes`はOracle `Number(2,0)` と`Number(3,0)`にマップされ、逆にもマップされます

.NET構成ファイルのセクションを構成して代わりのデータ型マッピングを指定することで、このデフォルトの動作は変更できます。

## データ型のマッピングおよびカスタマイズの手順

カスタム・マッピングを有効にするには、EDM作成の前に、.NET構成ファイルにマッピング情報を追加します。

マッピング情報を提供する前にすでにEDMが作成されている場合、Visual Studioツールを使用するか、または手動でマッピングを変更できます。Visual Studioを使用して、EDMの「Model Browser」ページに移動します。新しいデータ型のマッピングが必要な表を右クリックし、ポップアップ・メニューから「Table Mapping」を選択します。通常は画面の一番下に「Mapping Details」ウィンドウが表示されます。必要に応じて「Column Mappings」を更新します。

マッピングを追加または削除する必要がある場合、プロジェクトの既存のEDMXファイルのCSDLマッピング・セクションでTypeの値を見つけます。それらのTypeの値を、アプリケーションで使用する.NETデータ型に追加するか、削除します。次の例では、`BOOLCOL`および`BYTECOL`のプロパティ・ネーム・タイプがCSDLに追加され、それぞれBooleanおよびByteにマップされています。

CSDLカスタマイズ前のマッピングの例:

    <Property Name="INT16COL" Type="Int16" Nullable="false" />

CSDLカスタマイズ後のマッピングの例:

    <Property Name="BOOLCOL" Type="Boolean" Nullable="false" />
    <Property Name="BYTECOL" Type="Byte" Nullable="false" />
    <Property Name="INT16COL" Type="Int16" Nullable="false" />

予定しているマッピングの変更に応じて、これらのカスタマイズの可能性を組み合せて使用できます。多数の表および多数の列でマッピングの変更が必要な場合、EDMXファイルを削除してデータ・モデルを再生成する方法が最も効率的です。少数の表および多数の列で変更が必要な場合、影響を受ける表を削除してEDMXファイルを保存し、「Update Model from Database...」 を選択してこれらの表を再度含めます。単一の表および1つまたは2つの列のみで変更が必要な場合、手動で、または「Mapping Details」ウィンドウを使用してEDMXを変更します。

注意:

関数インポートからの複合型を作成するためにEDMウィザードを使用する場合、指定される任意のカスタムEDMタイプ・マッピングは自動では適用されません。EDMウィザードはデフォルト・タイプ・マッピングを使用します。開発者は、結果複合型を手動で編集する必要があります。開発者は複合型が生成された後にこのプロセスを開始します。BooleanではなくDecimalなど望ましくないタイプ・マッピングを持つ複合オブジェクトのあらゆる型宣言(フィールド、プロパティ、コンストラクタ・パラメータなど)は、望ましいタイプに手動で編集してください。

## StoreGeneratedPattern列挙体

次の各項では、Identity属性およびVirtual列について説明します。

### Identity属性

Oracle Database 12c (12.1)およびそれ以降のバージョンでは、Identity属性列の表またはビューをサポートしています。Oracleには、3つのIdentity属性タイプがあります。EDMウィザードによって、表またはビューを含むOracle Identity属性からデータ・モデルが生成される際に、3つのOracle Identity属性タイプのそれぞれについて、ODP.NETによって`.edmx`ファイルの`Identity`に`StoreGeneratedPattern`の値が設定されます。Identity属性に関連する列は、`INSERT`中にサーバー生成値を使用します。したがって、アプリケーション開発者は、順番やトリガーを作成する必要がありません。.NETアプリケーション自体がIdentity属性を設定する場合、この値は無視されます。

Identity属性をサポートしていないOracle Database 11gリリース2 (11.2)およびそれ以前のバージョンでは、アプリケーション開発者は、モデル生成後にエンティティ・モデル・デザイナ・プロパティで、列の`Identity`に`StoreGeneratedPattern`を手動で設定し、`INSERT`トリガーを作成することができます。`sys_guid()`のようなサーバー機能が列の値を生成できる場合は、データ・タイプによっては順番が必要ないこともあります。

### Virtual列

Oracle Database 11g (11.1)およびそれ以降のバージョンでは、式をVirtual列(Generated列とも呼ばれる)として、ベース表に直接格納できます。Virtual列を挿入または更新することはできません。ODP.NETによって、Virtual列のEFモデルの`Computed`に`StoreGeneratedPattern`は、自動で設定されません。エラーを回避するために、アプリケーション開発者は、モデル生成後のVirtual列の`Computed`に`StoreGeneratedPattern`の値を追加するか、または変更する必要があります。これにより、`SaveChanges()`の呼出し時に、Virtual列は`INSERT`および`UPDATE`から除外されます。

## カスタム・マッピングの使用時の比較エラーの解決

.NET構成ファイルのカスタム・マッピングを変更した場合、変更によって発生した比較エラーを解決するには、データ・モデルを再生成します。

場合によっては、カスタム・マッピングを使用するプロジェクトがVisual Studioによってロードされる際に、カスタム・マッピングが原因で比較エラーが発生することがあります。特定のシナリオの1つは、Visual Studioが以前はなかったエラーを生成するようになった既存のカスタム・マッピング付きのプロジェクトを開くときです。この場合、次の回避策を使用できます。

1. Visual Studioのヘルプ「About Microsoft Visual Studio」を開きます。「OK」をクリックしてダイアログ・ボックスを終了します。

   かわりに、Server Explorerで使用する接続を開きます。

2. プロジェクトを再コンパイルしてコンパイル・エラーを消去します。

## カスタムINSERT、UPDATEおよびDELETEストアド・プロシージャでのブール・パラメータおよびguidパラメータのマッピング

ストアド・プロシージャのマッピングにカスタム`INSERT、UPDATE`または`DELETE`ストアド・プロシージャを使用すると、次のエラーが発生する場合があります。

`エラー2042: 指定されたパラメータ・マッピングが無効です。`

これは、`Number`パラメータが`Boolean`属性にマップされた場合または`RAW`パラメータが`Guid`属性にマップされた場合に発生します。

解決策として、SSDLでストアド・プロシージャの`Number`パラメータに`Precision="1"`を、RAWパラメータに`MaxLength="16"`を手動で追加します。