17
22

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

AccessデータベースでEntityFrameworkを使ったコードファーストなモデル開発

Last updated at Posted at 2017-03-07

はじめに

EntityFrameworkはOleDBに非対応で事実上利用不可、
UWPではついにSQLiteにその座を奪われたりと、
もはや過去の遺物みたいな扱いを受けてるAccessですが、
JetEntityFrameworkなるものを見つけたので、試してみます。

参考

Microsoft Access Entity Framework Provider - GitHub

作ってみる

環境など

  • Visual Studio 2015 Update3
  • Access 2010(.accdb 2007-2010形式)
  • JetEntityFrameworkProvider v1.2.6

新規プロジェクトの作成

  • Windowsクラシックなアプリ(.Net 4.6.1)を新規作成します。
    VS New Project
    今回はC#&WPFを選んでいますが、VB&Windowsフォームでも同じ手順で実装可能です。

新規データベースの作成

  • Accessからデータベースファイルを作成します。
    ここではC:\Temp\Main.accdbに置きました。
    Access New Database
    この時点ではまだテーブルも何も存在しません。

ちなみにこのJetEntityFrameworkですがaccdbでなくmdbも対応しているそうです。
(OleDbでいけるから当然といえば当然)

VB&Windowsフォームでmdb…
負の遺産レガシーな業務アプリを細々と運用する現場には
あながちありがちな組み合わせではないでしょうか。

ライブラリインストール

NuGetパッケージマネージャを開き、JetEntityFrameworkをインストールします。
(依存関係のEntityFramework6は勝手についてきます。)
SnapCrab_NoName_2017-3-4_23-10-8_No-00.png

データベースの接続情報

App.configに先ほど作成したAccessデータベースのConnectionStringsを追記します。
MainConnectionの名前で作成しました。

App.config
  <connectionStrings>
    <add name="MainConnection" connectionString="Provider=Microsoft.Ace.OleDb.12.0;Data Source = C:\Temp\Main.accdb"
         providerName="JetEntityFrameworkProvider"/>
  </connectionStrings>

POCO Entityクラスの作成

コードファーストなので、まずはモデルを表すコードを書きます。
クラス名がテーブル名、プロパティがフィールド名になります。

  • 仮に商品マスターを分類管理するようなイメージで作ってみます。
    class Shohin
    {
        public int Sku { get; set; }
        public string Jan { get; set; }
        public string Name { get; set; }
        public decimal Price { get; set; }
        public virtual List<Bunrui> Bunrui { get; set; }
    }

    class Bunrui
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public virtual List<Shohin> Shohin { get; set; }
    }

Contextクラスの作成

Entityクラスとデータベースの橋渡しとなるのがコンテキストクラスです。
DbContextを継承したContextクラスを作成します。

  • System.Data.Entity名前空間のクラスを使っていきます。
using System.Data.Entity;
  • 継承元のコンストラクタに先ほどApp.configで定義したMainConnectionを引数で渡します。
    これが、このContextクラスを使用する際の接続情報になります。
  • DbSetプロパティを定義して、テーブルとEntityクラスをマッピングします。
  • Fluent APIを利用し、OnModelCreatingメソッド内でShohinクラスの主キーにSkuプロパティを指定しています。
    (EFの規約ではプロパティ名がIdのものが主キーとされるため、Idが無いShohinクラスはこのままでは使えません。)
    class Context:DbContext
    {
        public Context() : base("MainConnection")
        {
        }

        public DbSet<Shohin> Shohin { get; set; }
        public DbSet<Bunrui> Bunrui { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Shohin>()
                .HasKey( _ => _.Sku);
        }
    }

アプリ起動、テーブル生成

準備は整ったので、実際にテーブルが生成されるところを確認します。

  • メインフォームのコンストラクタに先ほどのContextクラスを使う処理を追記。
    とりあえず商品マスタの個数を数える感じで。
        public MainWindow()
        {
            InitializeComponent();

            using (var context = new Context())
            {
                Console.WriteLine(context.Shohin.Count());      
            }
        }
  • アプリをビルド&実行します。
    ここまでにミスが無ければ、さくっとアプリが立ち上がると思います。

  • Accessデータベースを見てみます。
    ShohinBunruiに多対多の関係を持たせたので、テーブルShohinsBubruis
    そして中間テーブルShohinBunruisの3テーブルが作成されました。賢いですね!
    無題.png
    (クラス名/テーブル名に日本語使ってしまったので複数形が残念なテーブル名になってます…)

おわりに

Fluent APIも使えますし、
通常のEntityFrameworkと同じ形で違和感なくAccessが扱えるようです。

EFv1は2008年リリースです。今更EFなんて~、と思う人も多いと思うんですが、
このJetEntityFrameworkが2015年に登場して、未だそれなりに更新されているあたりに
Accessの根強い人気(?)根深い闇(?)を感じます。

17
22
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
22

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?