LoginSignup
1
3

More than 1 year has passed since last update.

【C#】SQL Server (Docker コンテナ) をDatabase Firstで操作してみる

Posted at

タイトルもうちょっとどうにかならんかったか・・・orz

この記事は

  1. Microsoft SQL Server 2019のDockerコンテナを立て
  2. C#のEF Coreを使ってDBにアクセスし
  3. 簡単なCRUD動作を試す

Docker Desktop for Windows をインストールする

下記記事の動作確認まで行う(CentOSは不要)

Powershellでdocker -vする
Dockerが正しくインストールされていれば、それらしき文字列が表示される

versionが表示されればOK
> docker -v
Docker version 20.10.5, build 55c4c88
# ↑それらしき文字列

SQL Server 2019のコンテナを立てる

Docker Hub の Description に沿って進む

イメージをプルする

2019-latestを指定する

> docker pull mcr.microsoft.com/mssql/server:2019-latest
2019-latest: Pulling from mssql/server

コンテナを立てる

パスワードには要件がある 8文字以下のパスワードを設定すると、コンテナが`RUNNING`状態にならない

Microsoft SQL Server の強力なパスワードの要件

コンテナを立てる
# PORTは11433にした
docker run --name sql1 -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=SqlPass1234' -p 11433:1433 -d mcr.microsoft.com/mssql/server:2019-latest

Powershellでdocker psを実行すると、sql1という名前のコンテナが生成されていることがわかる

プロセス確認
> docker ps
CONTAINER ID   IMAGE                                        COMMAND                  CREATED          STATUS          PORTS                     NAMES
8097100726be   mcr.microsoft.com/mssql/server:2019-latest   "/opt/mssql/bin/perm…"   24 minutes ago   Up 10 minutes   0.0.0.0:11433->1433/tcp   sql1

同様に、Docker Desktop の Container/Apps をみれば、PORT: 11433RUNNING状態であることがわかる

image.png

参考:DockerでSQL Serverを建ててsqlcmd, SSMS, JDBCでアクセスする

新しいデータベースをつくる

SSMSでDockerのSQL Serverへ接続する

Dockerコンテナ(localhost, PORT 11433)にアクセスする

image.png

MyDockerDBデータベースを新規作成し、さらにBlogTbテーブルを追加した
Idは主キーかつIDENTITYを指定している

image.png

WPFプロジェクトをつくる

適当に作業用ディレクトリを作成し、Powershellでコマンドを打っていく
このプロジェクトからDBを操作する

Powershell
# 1. プロジェクトを作成する
> dotnet new sln
テンプレート "Solution File" が正常に作成されました。

> dotnet new wpf -o MainProject
テンプレート "WPF Application" が正常に作成されました。

> dotnet sln add .\MainProject\MainProject.csproj
プロジェクト `MainProject\MainProject.csproj` をソリューションに追加しました。

> cd .\MainProject\

# 2. DB操作に必要なパッケージをインストールする
> dotnet add package Microsoft.EntityFrameworkCore.Tools
  復元対象のプロジェクトを決定しています...
# 以下同じ手順で4つのパッケージをインストールする

> dotnet list package
プロジェクト 'MainProject' に次のパッケージ参照が含まれています
   [net5.0-windows7.0]:
   最上位レベル パッケージ                                   要求済み    解決済み
   > Microsoft.EntityFrameworkCore                5.0.9   5.0.9
   > Microsoft.EntityFrameworkCore.Design         5.0.9   5.0.9
   > Microsoft.EntityFrameworkCore.SqlServer      5.0.9   5.0.9
   > Microsoft.EntityFrameworkCore.Tools          5.0.9   5.0.9

Visual Studioのパッケージマネージャー コンソールからGet-Helpを打ち
EFユニコーンが表示されればOK

パッケージマネージャーコンソール
> Get-Help about_EntityFrameworkCore

                     _/\__
               ---==/    \\
         ___  ___   |.    \|\
        | __|| __|  |  )   \\\
        | _| | _|   \_/ |  //|\\
        |___||_|       /   \\\/\\

プロジェクトにDBを移植する

先にSSMSで作っておいたBlogTbをプロジェクトに移植する
移植という言葉は適切ではないかもしれない
いわゆるデータファーストで、さっきつくったMyDockerDBをC#のモデルとして取り込む

EF Core ではないけれど参考↓

データベースへ接続する

Visual Stduio のツール(T)>データベースへの接続(D)

image.png

サーバーエクスプローラーに追加されたDBを右クリックしてプロパティの中の"接続文字列"をメモしておく

image.png

データベースをもとにモデルを自動作成する

MyDockerDBデータベースからモデルとコンテキストを自動生成する

パッケージマネージャーコンソール
> Scaffold-DbContext 'Data Source="localhost, 11433";Initial Catalog=MyDockerDB;User ID=sa;Password=SqlPass1234' Microsoft.EntityFrameworkCore.SqlServer
Build started...
Build succeeded.
To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see http://go.microsoft.com/fwlink/?LinkId=723263.

# Google翻訳
# 接続文字列内の潜在的に機密性の高い情報を保護するには、ソースコードから情報を移動する必要があります。 Name =構文を使用して構成から接続文字列を読み取ることにより、接続文字列のスキャフォールディングを回避できます。 

接続文字列がまる見えだと怒られつつも、プロジェクト内にMyDockerDBContext.cs(コンテキスト)とBlogTb.cs(POCOモデル)が生成された

image.png

Scaffold-DbContextのオプションを明記すれば、ModelやContextの生成先などを細かく指定できる

接続文字列の保護に関するお作法↓↓

CRUD操作をしてみる

CRUD用に4つメソッドを用意して、SSMSでDBの様子を都度確認する

Animation2.gif

連続的にレコードを追加して、読み取って、更新して、連続的に削除して・・・をしている。

MainWindow.xaml.cs(コードビハインド)
        // 上から Create, Read, Update, Delete
        private void Button_Click1(object sender, RoutedEventArgs e)
        {
            _context.Add(new BlogTb() { Title = "a", Date = new System.DateTime() }); // Idは連番で勝手に振られる
            _context.SaveChanges();
        }
        private void Button_Click2(object sender, RoutedEventArgs e)
        {
            var d = _context.BlogTbs.FirstOrDefault();
            MessageBox.Show(d.Title);
        }
        private void Button_Click3(object sender, RoutedEventArgs e)
        {
            var d = _context.BlogTbs.FirstOrDefault();
            d.Title = "last"; // 先頭のタイトルをlastに変更する
            _context.SaveChanges();
        }
        private void Button_Click4(object sender, RoutedEventArgs e)
        {
            var d = _context.BlogTbs.FirstOrDefault();
            _context.Remove(d); // 先頭を削除する
            _context.SaveChanges();
        }

当たり前のように、このままだと
空のテーブルになってもなおDELETEをするとエラーになる

おわりに

普段 Docker は使わないので、言葉遣いや操作に誤りがあれば、ご指摘いただけると幸いです

参考にさせていただいた記事

1
3
0

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
1
3