C#製 micro O/RマッパーNPocoの紹介 - 概要編

C# で使える O/RマッパーのNPocoに関する日本語の記事が見当たらなかったので書いてみます。

## NPocoって何？
C#製のO/Rマッパーで、EntityFrameworkとDapperの中間くらいの立ち位置のO/Rマッパーです。
拡張するポイントもいくつか用意されいます。

[リポジトリ](https://github.com/schotime/NPoco)
2020年06月時点で最終リリースが10か月前と少し不安ですが
issueの回答などは行われています。

今回は`NPoco 4.0.2` を使いました
データベースは `PostgreSQL 12`を使っています。

## テーブルの用意
今回は以下のような単純なテーブルを用意しました。

### emp

| 列名       | 型         | 主キー|
|-----------|------------|-------|
|emp_id     |varchar(5)  |1      |
|first_name |varchar(10) | |
|family_name|varchar(10) | |
|created_at |timestamp   | |

## コード

以下のように使います。

まずテーブルに対応したクラスを用意します。

```cs:Emp.cs
    [TableName("emp")]//テーブル名
    [PrimaryKey("emp_id", AutoIncrement = false)]//AutoIncrement = falseとしておかないと自動採番対象とみなされてしまう。
    public class Emp
    {
        [Column("emp_id")]
        public string EmpId { get; set; }

        [Column("first_name")]
        public string FirstName { get; set; }

        [Column("family_name")]
        public string FamilyName { get; set; }

        [Column("created_at")]
        public DateTime? CreatedAt { get; set; }

        public override string ToString()
        {
            return $"[EmpId={EmpId}, FirstName={FirstName}, FamilyName={FamilyName}, CreatedAt={CreatedAt}]";
        }
    }
```

実際に動かすコードです。

```cs:Sandbox01Main.cs

    public class Sandbox01Main
    {
        //PostgreSQL用接続文字列
        private const string connectionString = "Host=localhost;Database=test_db;Username=test_user;Password=test_user";

        public void Start()
        {
            //DbConnectionの準備
            using NpgsqlConnection con = new NpgsqlConnection(connectionString);
            con.Open();
            //NPocoの操作の中心となるクラスを作成
            using Database database = new Database(con);

            database.BeginTransaction();
            try
            {
                //インサート
                var emp = new Emp
                {
                    EmpId = "00001",
                    FirstName = "Taro",
                    FamilyName = "Tanaka",
                    CreatedAt = DateTime.Now,
                };
                database.Insert(emp);

                //セレクト
                Emp selectedEmp1 = database.Query<Emp>()
                                    .Where(x => x.EmpId == "00001")
                                    .SingleOrDefault();
                Console.WriteLine("取得した値");
                Console.WriteLine(selectedEmp1);


                //アップデート
                var ss = database.StartSnapshot(selectedEmp1);
                selectedEmp1.FirstName = "Jiro";
                //変更した列だけ更新
                database.Update(selectedEmp1, ss.UpdatedColumns());


                Emp selectedEmp2 = database.Query<Emp>()
                                    .Where(x => x.EmpId == "00001")
                                    .SingleOrDefault();
                Console.WriteLine("更新後,再取得した値");
                Console.WriteLine(selectedEmp2);


                //デリート
                database.Delete(selectedEmp2);


                bool exists = database.Query<Emp>()
                                  .Where(x => x.EmpId == "00001")
                                  .Any();

                Console.WriteLine("削除後存在するか？");
                Console.WriteLine(exists);

                //トランザクションをコミット
                database.CompleteTransaction();
            }
            catch
            {
                //例外時はロールバック
                database.AbortTransaction();
                throw;
            }
        }
    }
```

### コードの解説
`Database` というクラスが`NPoco` の操作の中心となるクラスです。
このクラスからデータベースの操作を行います。
コンストラクタは複数用意されていますが今回は`DbConnection`を受け取るものを使いました。

`Insert`, `Update`, `Delete` メソッドでそれぞれのDMLが実行できます。
`Update` については更新対象の列のみを指定することができます。(省略した場合は全ての列が更新される。)

`Query<>` メソッドを使うことでLinq感覚でSQLを組み立てることができます。
オンメモリでの絞り込みではなく実際にWhere句による絞り込みが実行されています。

また今回は生SQLを使わなかったですが、生SQLを使ったDB操作も可能です。

## おわりに
今回は概要のみの説明をしました。

次回以降 それぞれの機能について解説していきたいと思います。

## つづき
- [NPocoの紹介 -機能編- Databaseクラス](https://qiita.com/epsilon_87_myo/items/f0091bfc783b90d81cbd)
- [NPocoの紹介 -機能編- クエリ自動生成](https://qiita.com/epsilon_87_myo/items/db68b1356edd40ce82d6)
- [NPocoの紹介 -機能編- 生クエリ](https://qiita.com/epsilon_87_myo/items/1d7fe0213742c68703ff)
- [NPocoの紹介 -機能編- ページング](https://qiita.com/epsilon_87_myo/items/60b02b26fe83e10a3f36)
- [NPocoの紹介 -機能編- インターセプター](https://qiita.com/epsilon_87_myo/items/a31c670fe70137c685ee)
- [NPocoの紹介 -カスタマイズ編- 空文字列をnullに変換して登録する](https://qiita.com/epsilon_87_myo/items/d2b09807abac45c3d265)