CData Software Blog

クラウド連携のCData Software の技術ブログです。

FluentTextTable(全角対応テキストテーブルライブラリ)を使ってみた

f:id:sugimomoto:20200726114056p:plain

こんにちは。CData Software Japan の杉本です。今回は至極個人的に業務上ありがたいライブラリを知ったので、その特定ユースケースでの書き残しです。

今日Twitter@nuits_jp さんがこんなツイートをしているのを見かけました。

@nuits_jp記事でも書かれているんですが、私も似たようなことやっているんですよね!(似たようなというのも失礼かもですが)

qiita.com

特に私の業務上、ADO.NET Provider・EntityFramework 経由で表形式のデータをよく扱うので、以下のようなデータをConsoleアプリでさっくり確認したいということがままあります。(LinqPadももちろん良い)

・サーバーエクスプローラーでSmaregi ADO.NET Providerのデータを表示

f:id:sugimomoto:20200726112144p:plain

ただ、とりあえずデバッグの補助として出力を確認できればいいか、程度の気持ちだったので、日本語の幅に対応する気も無く、列幅固定でぶった切り・・・。

ひどい例をあげると以下のような感じになっちゃうものです。(恥を忍んで晒してみる。)

f:id:sugimomoto:20200726112155p:plain

それをいい感じで出力してくれるのが、FluentTextTable

GithubとNugetで公開されています。

github.com

www.nuget.org

使い方はシンプルで「Build.TextTable().WriteLine(records)」にクラスを指定して、オブジェクトを渡してあげるだけ。

私は今回EntityFramework経由で取得したデータ(Productsという商品マスタテーブル)を以下のように渡してあげました。(詳しくは後述)

using System;
using System.Linq;
using FluentTextTable;
using EntityFrameworkCoreSample.Models;

namespace EntityFrameworkCoreSample
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            var context = new SmaregiContext();

            Build.TextTable<Products>(
                builder =>
                {
                    builder
                    .Columns.Add(x => x.ProductName)
                    .Columns.Add(x => x.ProductCode)
                    .Columns.Add(x => x.ProductKana);
                }
                ).WriteLine(context.Products.Take(10));
        }
    }
}

それが、こんな感じで出力できます!

f:id:sugimomoto:20200726112208p:plain

そのままWriteLineでまるごと渡してもいいですが、TextTableの引数で表示したいカラムや右寄せ左寄せなど、かなり細かな調整ができるのがありがたいですね・・・!

このあたりのできることは、Githubにかなり細かく説明が書かれています。

https://github.com/nuitsjp/FluentTextTable/blob/master/README-ja.md#%E7%9B%AE%E6%AC%A1

あとDBで日本語のカラム名を使って、スキャフォールディングをした場合、日本語のClass・Property名を扱うことがままあるのですが、(CData ADO.NET kintoneとか)

using System;
using FluentTextTable;

namespace EntityFrameworkCoreSample
{
    class Program
    {
        class ユーザー
        {
            public string 名前 { get; set; }
            public int 年齢 { get; set; }
        }

        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            var user = new[]
            {
                new ユーザー {名前 = "高橋太郎", 年齢 = 33},
                new ユーザー {名前 = "高橋太助", 年齢 = 44}
            };

            Build.TextTable<ユーザー>().WriteLine(user);

        }
    }
}

それも大丈夫そうです!

f:id:sugimomoto:20200726112823p:plain

@nuits_jp さん、ありがとうございます!

という、完全に個人的にありがたかった! という記事でした。

あとは、今までCData Blogでも取り上げていなかった、EntityFramework Coreを利用する場合の環境構築方法です。

EntityFramework Core スキャフォールディングの使い方

環境準備

FluentTextTableは配列でもListでも単一オブジェクトでもなんでも良さげですが、私はEntity Framework・自社 ADO.NET Provider経由で取得したもので試したかったので、以下を使っています。

https://www.cdata.com/jp/drivers/smaregi/ado/

f:id:sugimomoto:20200726113056p:plain

CData ADO.NET Provider for Smaregi 2019J - EFCore コンソールアプリ

この辺は最終的にDapperでもSqlKataでも大丈夫でしょう。

kageura.hatenadiary.jp

kageura.hatenadiary.jp

とりあえず、.NET Coreで新しいコンソールアプリプロジェクトを作成します。

f:id:sugimomoto:20200726113104p:plain

プロジェクトを作成したら、「EntityFrameworkCore」それから「EntityFrameworkCore.Relational」をインストールします。

Install-Package Microsoft.EntityFrameworkCore
Install-Package Microsoft.EntityFrameworkCore.Relational

続いて、「Smaregi ADO.NET Provider」をインストールしたフォルダーにある、以下の2つのDLLを参照に加え

\lib\netstandard2.1\EFCORE30\CData.EntityFrameworkCore.Smaregi.dll
\lib\netstandard2.0\System.Data.CData.Smaregi.dll

プロジェクトに「既存の項目」として、以下のライセンスファイルを追加します。追加したライセンスファイルは「出力ディレクトリにコピー」のプロパティを「新しい場合はコピーする」にしておきましょう。

\lib\netstandard2.0\System.Data.CData.Smaregi.lic

f:id:sugimomoto:20200726113112p:plain

これでEntityFrameworkの環境準備は完了です。

続いて、ContextクラスとOR/Mのクラス定義ですが、スキーマからClassの生成にはスキャフォールディングを使用しました。

http://cdn.cdata.com/help/UXE/jp/ado/pg_efCoreScaffolding.htm

パッケージマネージャーコンソールから「EntityFrameworkCore.Tools」を追加して

Install-Package Microsoft.EntityFrameworkCore.Tools

対象のテーブルをスキャフォールドします。今回は商品マスタが格納されているProductsテーブルを対象としました。ContractIdとAccessTokenの指定はこちらの記事を参照。

Scaffold-DbContext "ContractId=mycontractid;AccessToken=myaccesstoken;" CData.EntityFrameworkCore.Smaregi -OutputDir Models -Context SmaregiContext -Tables Products

これでContextクラスとProductsテーブルにマッピングされたクラスが定義されました。

f:id:sugimomoto:20200726113128p:plain

あとは、最初に書いていた通り、EntityFrameworkとしてデータを呼び出して、FluentTextTableに渡してあげるだけです。

using System;
using System.Linq;
using FluentTextTable;
using EntityFrameworkCoreSample.Models;

namespace EntityFrameworkCoreSample
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            var context = new SmaregiContext();

            Build.TextTable<Products>(
                builder =>
                {
                    builder
                    .Columns.Add(x => x.ProductName)
                    .Columns.Add(x => x.ProductCode)
                    .Columns.Add(x => x.ProductKana);
                }
                ).WriteLine(context.Products.Take(10));
        }
    }
}

いいですね!

f:id:sugimomoto:20200726113134p:plain