Grow up

生活とプログラミング

Setup DB First EntityFramework SQLite

f:id:knkomko:20201114012601p:plain


ソリューションファイルの作成

サンプルとして Windows Form アプリケーションを作成しました。
f:id:knkomko:20201113222821p:plain:w300

1. SQLite Compact Toolbox のインストール

拡張機能の管理から SQLite/SQL Server Compact Toolbox をインストールします。
f:id:knkomko:20201113223609p:plain

2. GAC に SQLite をインストール

sqlite-netFx46-setup-bundle-x86-2015-1.0.113.0.exe をダウンロードします。
デザイナコンポーネントは64bit版には含まれていないため32bit版を使用します。
f:id:knkomko:20201113230709p:plain

GACにインストール、デザイナコンポーネントのインストールを選択します。
f:id:knkomko:20201113230318p:plain

ちなみに64bit版のSetupだとデザイナーコンポーネントの選択がありません。
f:id:knkomko:20201113231439p:plain

GACに登録されている事をToolboxから確認します。
f:id:knkomko:20201113232257p:plain

3. System.Data.SQLite NuGet パッケージのインストール

C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\machine.configの
DbProviderFactories タグからバージョン番号を確認します。
f:id:knkomko:20201113234335p:plain

上記で確認したバージョン番号と同じ NuGet パッケージをインストールします。
NuGet Gallery | System.Data.SQLite 1.0.113.6
f:id:knkomko:20201113235317p:plain

インストール後の packages.config

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="EntityFramework" version="6.3.0" targetFramework="net48" />
  <package id="Stub.System.Data.SQLite.Core.NetFramework" version="1.0.113.3" targetFramework="net48" />
  <package id="System.Data.SQLite" version="1.0.113.0" targetFramework="net48" />
  <package id="System.Data.SQLite.Core" version="1.0.113.6" targetFramework="net48" />
  <package id="System.Data.SQLite.EF6" version="1.0.113.0" targetFramework="net48" />
  <package id="System.Data.SQLite.Linq" version="1.0.113.0" targetFramework="net48" />
</packages>

インストール後の App.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
  </startup>
  <entityFramework>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
      <provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
    </providers>
  </entityFramework>
  <system.data>
    <DbProviderFactories>
      <remove invariant="System.Data.SQLite.EF6" />
      <add name="SQLite Data Provider (Entity Framework 6)" invariant="System.Data.SQLite.EF6" description=".NET Framework Data Provider for SQLite (Entity Framework 6)" type="System.Data.SQLite.EF6.SQLiteProviderFactory, System.Data.SQLite.EF6" />
    <remove invariant="System.Data.SQLite" /><add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".NET Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" /></DbProviderFactories>
  </system.data>
</configuration>

今回のApp.configには設定が不足している為 providers タグに設定を追加します。
f:id:knkomko:20201114002938p:plain

変更後の App.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
  </startup>
  <entityFramework>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
      <provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
      <provider invariantName="System.Data.SQLite" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
    </providers>
  </entityFramework>
  <system.data>
    <DbProviderFactories>
      <remove invariant="System.Data.SQLite.EF6" />
      <add name="SQLite Data Provider (Entity Framework 6)" invariant="System.Data.SQLite.EF6" description=".NET Framework Data Provider for SQLite (Entity Framework 6)" type="System.Data.SQLite.EF6.SQLiteProviderFactory, System.Data.SQLite.EF6" />
    <remove invariant="System.Data.SQLite" /><add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".NET Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" /></DbProviderFactories>
  </system.data>
<connectionStrings><add name="EmployeeDBContext" connectionString="data source=C:\Users\q612.TOHNICHI\source\repos\SQLiteEFSample\Employee.db" providerName="System.Data.SQLite.EF6" /></connectionStrings></configuration>
4. DBファーストの使用

DBファースト用に department テーブルを作成します。
f:id:knkomko:20201114000757p:plain

DBの作成には DB Browser for SQLite を使用しました。
Downloads - DB Browser for SQLite

ADO.NET Entity Data Model を作成します。
f:id:knkomko:20201114001047p:plain

データベースから Code First を選択します。
f:id:knkomko:20201114001148p:plain

SQLite Provider (Simple for EF6 by ErikEJ) を使用します。
f:id:knkomko:20201114001615p:plain

Data Source にDBのファイルパスを指定します。
f:id:knkomko:20201114001730p:plain

テーブルを指定します。
f:id:knkomko:20201114001824p:plain

Department と DBContext が作成されました。
f:id:knkomko:20201114005254p:plain

全件検索した結果を一覧表示します。

using System;
using System.Linq;
using System.Windows.Forms;

namespace SQLiteEFSample
{
    using Model;

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            using (EmployeeDBContext context = new EmployeeDBContext())
            {
                DataGridView.DataSource = context.Department.AsNoTracking().ToList();
            }
        }
    }
}

無事 department テーブルの一覧を表示する事ができました。
[f:id:knkomko:20201114005346p:plain:300]

補足 App.config の修正を行わなかった場合の動作

不足していた System.Data.SQLite を追加せず実行した場合の動作です。

      <provider invariantName="System.Data.SQLite" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />

SQLの発行を行う際に InvalidOperationException が発生します。

System.InvalidOperationException: 'No Entity Framework provider found for the ADO.NET provider with invariant name 'System.Data.SQLite'. Make sure the provider is registered in the 'entityFramework' section of the application config file. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information.'

f:id:knkomko:20201114002230p:plain