空のプロジェクトからASP.NET MVC5 EntityFramework6 for Oracleを試す

#経緯
前記事「[空のプロジェクトからASP.NET MVC5 EntityFramework6](http://qiita.com/yaju/items/498473ae41156df6e5a5)」では、SQL Serverによる接続でしたが、仕事で主に使うデータベースはOracleであるため、Oracleで同じことが出来るのかを確認する。
仕事の合間を使って確認したかったが空き時間が出来なかったため、自宅で確認することにした。
自宅なので無料版の「Oracle Database Express Edition 11g Release 2 for Windows x64」を[ダウンロード](http://www.oracle.com/technetwork/jp/database/database-technologies/express-edition/downloads/index.html)してインストールしている。

#環境
* Windows 10 Home 64bit
* Oracle Data 11g Express Edition 64bit
* Visual Studio 2015 Community
* SQL Developer 4.1.3

#Oracleユーザーの作成
今回、スキーマ名(ユーザー名)は「TEST」で作成しました。
参照:[Oracle Database 11g Express Edition -ただでOracleのデータベース使いましょう。](http://qiita.com/GohanOmori/items/0b58a656174c767e239e)

#ODP.NET版のEntity Frameworkのインストール
Visual StudioのNuGetパッケージの管理にて「Oracle」で検索します。
「Oracle.ManagedDataAccess.EntityFramework」をインストールします。
もう1つの「Oracle.ManagedDataAccess」は自動的に一緒にインストールされます。

![OracleMangerInstall.png](https://qiita-image-store.s3.amazonaws.com/0/14053/6f728ffe-f22a-e424-eddd-363f424b414c.png)

![OracleMangerInstall2.png](https://qiita-image-store.s3.amazonaws.com/0/14053/d0bebbb9-7423-e3f5-2fc7-a89860fa5ea2.png)

#ODP.NET Managed Driver(管理対象ドライバ)について
すべてがマネージコードで記述されているフルマネージドなドライバになります。 
このため、これまでのODP.NETとは違いネイティブなドライバ(Instant Clientなど)を必要としない軽量なドライバになっています。

* Oracleクライアントが不要
* TNS設定をWeb.configやApp.configに定義可能
* 名前空間がOracle.DataAccessからOracle.ManagedDataAccessに変更された
* NET Framework 4以降で使用可能
* Oracle 10g R2以降で使用可能
* [管理対象外ドライバではサポートされている一部の機能がサポートされていない](http://docs.oracle.com/cd/E49329_01/win.121/b72971/intro004.htm)

これまでも、System.Data.OracleClientを使えばOracleクライアントは不要でしたが、.NET4以降では非推奨となっています。また、Oracleに最適化されているわけではないので、Oracleのバージョン違いによるプロパティ指定やフェッチ制御の細かな設定などは指定できませんでした。
Javaの場合、Oracle Thin JDBC Driverを使えば、Oracle クライアントを介さずせずに直接 Oracleに接続することができるので、やっとJavaに追いついた感じですかね。

#Web.configの変更
Web.configの変更する部分のみ抽出

```xml:変更前Web.config
  <connectionStrings>
    <add name="StandardContext" connectionString="Data Source=(local);Initial Catalog=yaju;User ID=sa;Password=admin;" providerName="System.Data.SqlClient"/>
    <add name="OracleDbContext" providerName="Oracle.ManagedDataAccess.Client"
      connectionString="User Id=oracle_user;Password=oracle_user_password;Data Source=oracle"/>
  </connectionStrings>

 <oracle.manageddataaccess.client>
    <version number="*">
      <dataSources>
        <dataSource alias="SampleDataSource" descriptor="(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=ORCL))) "/>
      </dataSources>
    </version>
  </oracle.manageddataaccess.client>
```
SQLServer版のStandardContextをコメントアウトしてOracleDBContextをStandardContextに変更します。Oracle Database 11g Express Editionのサービス名は一般的に「XE」(tnsnames.oraを確認)となっているため、「ORCL」から「XE」に変更します。

```xml:変更後Web.config
  <connectionStrings>
    <!-- <add name="StandardContext" connectionString="Data Source=(local);Initial Catalog=yaju;User ID=sa;Password=admin;" providerName="System.Data.SqlClient"/> -->
    <add name="StandardContext" providerName="Oracle.ManagedDataAccess.Client"
      connectionString="User Id=test;Password=fuga;Data Source=XE"/>
  </connectionStrings>

  <oracle.manageddataaccess.client>
    <version number="*">
      <dataSources>
        <dataSource alias="XE" descriptor="(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=XE))) "/>
      </dataSources>
    </version>
  </oracle.manageddataaccess.client>
```

#例外エラーが発生
Web.configを変更して実行するとエラー「ユーザー'dbo'は存在しません」が発生しました。
![OracleError.png](https://qiita-image-store.s3.amazonaws.com/0/14053/9f3d9375-4837-6fd3-d718-231c60c6ef0b.png)

ネットにて「ユーザー'dbo'は存在しません」で検索すると下記サイトがヒット
[【ASP.NET（MVC）】ODP.NET　Entityデータモデルからのテーブル作成・操作について](http://qa.atmarkit.co.jp/q/9712)
> 接続するDB（ドライバ）にかかわらずデフォルトのユーザーは「dbo」となるため、スキーマを指定することで解決。
modelBuilder.HasDefaultSchema("スキーマ名");
チュートリアル
[Entity Framework Code First and Code First Migrations for Oracle Database](http://www.oracle.com/webfolder/technetwork/tutorials/obe/db/dotnet/CodeFirst/index.html#section1)

#スキーマを指定
ModelsのStandardContext.csにて、OnModelCreatingメソッドを追加する。

```csharp:StandardContext.cs
namespace MvcBasic.Models
{
    public class StandardContext : DbContext
    {
        public DbSet<Book> Books { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            //スキーマを指定（デフォルトではdbo）
            modelBuilder.HasDefaultSchema("TEST");　　
        }
    }
}
```

#最終結果
※ViewsのShared内のHeader.cshtmlとFooter.cshtmlは「MvcBasic」に変更しました。
![OracleResult.png](https://qiita-image-store.s3.amazonaws.com/0/14053/fe62aa61-4fb2-43b3-595d-625b62a8b0a1.png)

#今後について
今回Oracleを使用したが、Oracle内のテーブル自体を参照したわけではないので、本来のEntityFrameworkの機能を使っての参照と[登録・更新・削除](http://qiita.com/yaju/items/9ce95f3bc741d1af3dd7)を作成していきます。

#参照
[ODP.NET Managed Driver(管理対象ドライバ)についての私的まとめ](http://stknohg.hatenablog.jp/entry/2014/11/02/173039)
[Oracle Data Provider for .NET 12.1のODP.NET管理対象ドライバ](https://karuakun.wordpress.com/2013/11/13/oracle-data-provider-for-net-12-1%E3%81%AEodp-net%E7%AE%A1%E7%90%86%E5%AF%BE%E8%B1%A1%E3%83%89%E3%83%A9%E3%82%A4%E3%83%90/)
[ODP.NETをNuGetからインストールする](http://skill-note.net/post-692/)
[オラクルクライアントレスでの接続(.NET)](https://teratail.com/questions/7219)
[【C#】Oracleへの接続をクライアントインストール無しで行う](https://programchan.com/archives/47)
[EntityFrameworkとODP.NETを使ったアプリのデプロイ方法](http://www.cat-ears.net/?p=26975)
[ODP.NET Managed DriverでOracleクライアントいらず](http://www.fermata.mydns.jp/%E9%96%8B%E7%99%BA%E6%97%A5%E8%AA%8C/134-odp-net-managed-driver%E3%81%A7oracle%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88%E3%81%84%E3%82%89%E3%81%9A.html)