2022年01月

ゆかりすたー 4 NEBULA Ver 6.30 公開

nebulaゆかりすたー NEBULA Ver 6.30を公開しました。

ゆかりすたー NEBULA(ネビュラ)はカラオケ動画ファイルを整理し、ゆかり(持ち込みカラオケ用のブラウザリクエストツール)から検索できるようにするツールです。データベースを活用することにより、タイアップしている番組名や歌手名などの付加情報を含めて整理します。

Ver 6.02 以降は Microsoft Store での配布となっています(引き続き無料です)。それに伴い、Ver 4.60 以前からの更新に当たっては楽曲情報データベースの引き継ぎが必要となります。

ニコカラメーカー 2 Ver 11.23 公開

Storeニコカラメーカー 2 Ver 11.23 を公開しました。

ニコカラメーカー 2 は、カラオケ字幕動画ファイル(ニコカラ)を手軽に作ることができる字幕焼き付けツールです。画面の案内に従って操作を進めていくことで、ニコカラができあがる流れになっています。

今回より、Microsoft Store での配布となりました(引き続き無料です)。

ストア配布のメリット

Storeニコカラメーカー 2 およびゆかりすたー 4 NEBULA は、Microsoft Store(以降「ストア」と表記)での配布となりました(引き続き無料です)。

なぜストアで配布することにしたのかというと、以下のような様々なメリットがあるためです。

インストールがさらに簡単に

これまでもインストールは簡単でしたが、ストア配布によりさらにインストールが簡単になりました。

ストアの「入手」または「インストール」ボタンをクリックするだけでインストールが完了します。

スタートメニュー自動登録

インストールすると、スタートメニューにも自動的に登録されます。

(補足)
起動時はスタートメニューから起動してください。
旧 zip バージョンの時に作成したショートカットから起動すると旧バージョンが起動してしまいます。

SmartScreen による妨害がない

これまでは、アプリを起動しようとすると SmartScreen の画面が表示されて、いくつか画面をクリックしないと起動できない場合がありました。

ストア配布により SmartScreen が表示されなくなるため、起動が簡単になります。

更新がさらに簡単に

これまでも更新(バージョンアップ)は簡単でしたが、ストア配布によりさらに更新が簡単になりました。

更新版が公開されると、自動的に更新版がインストールされますので、何ら画面で操作する必要はありません。

(補足)
旧 zip 版からストア配布版への自動更新は行われません。
ストア配布のアプリを最初の 1 回はストアで入手する必要があります。

PC 買い換え時に楽

パソコンを買い換えた時や、あるいは Windows をクリーンインストールした時など、他のストアアプリと一緒にまとめてインストールすることができます。個別にインストールする必要がないので手間がかかりません。

ストア配布リンク


ゆかりすたー 4 NEBULA Ver 6.13 公開

listゆかりすたー NEBULA Ver 6.13 を公開しました。

ゆかりすたー NEBULA(ネビュラ)はカラオケ動画ファイルを整理し、ゆかり(持ち込みカラオケ用のブラウザリクエストツール)から検索できるようにするツールです。データベースを活用することにより、タイアップしている番組名や歌手名などの付加情報を含めて整理します。

Ver 6.02 より、Microsoft Store での配布となっています(引き続き無料です)。それに伴い、Ver 4.60 以前からの更新に当たっては楽曲情報データベースの引き継ぎが必要となります。

C# で SQLite を便利に使うサンプルコード(LINQ to SQLite)【改訂版】

.NET 6 C# で SQLite3 を使う方法について整理し、サンプルプログラムにまとめました。

C# では、文字列ベースのクエリよりも遙かに効率的かつミスが少なくプログラムすることができます。

サンプルプログラムは GitHub に上げてあります。

(補足)
本記事は、以前の記事を時代に合わせて改訂したものです。


使用するパッケージ

C# で SQLite を使うためには、Microsoft.EntityFrameworkCore.Sqlite パッケージを使用します。

以前はどのパッケージ(ライブラリ)を使うか少し迷うところもありましたが、現在は Entity Framework Core (EF Core) 一択でいいのではないでしょうか。

Microsoft.EntityFrameworkCore.Sqlite のインストール

NuGetインストールは簡単です。

  1. Visual Studio を起動し、SQLite を使いたいプロジェクトを開きます。
  2. メニューの[ツール|NuGet パッケージマネージャー|ソリューションの NuGet パッケージの管理]をクリック。
  3. 検索窓に「Microsoft.EntityFrameworkCore.Sqlite」と入力して SQLite パッケージを検索。
  4. 検索結果の Microsoft.EntityFrameworkCore.Sqlite を選択して、SQLite を使いたいプロジェクトにチェックを入れ、インストールボタンをクリック。関連するパッケージも含めて自動でインストールが終わります。
以上でインストール完了です。

テーブル構造定義クラスの作成

データへのアクセスを簡単・分かりやすくするために、テーブル構造を定義するクラスを作成します。

簡易名簿テーブル「t_test」が以下のような構造になっているとします。

フィールド名NULL備考
test_id整数不可連番、主キー
test_name文字列不可氏名、インデックス作成、ユニーク制約
test_height浮動小数身長

この場合、テーブル構造定義クラスは以下のようになります。

[Table("t_test")]
[Index(nameof(Name), IsUnique = true)]
internal class TTestData
{
    // ID
    [Key]
    [Column("test_id")]
    public Int32 Id { get; set; }

    // 氏名
    [Column("test_name")]
    public String Name { get; set; } = String.Empty;

    // 身長
    [Column("test_height")]
    public Double? Height { get; set; }
}

基本的には、カラムをプロパティーとして宣言するだけです。その際、[Column] 属性でデータベースファイルのフィールド名を指定しておきます。SQLite の実際の型についてはフレームワーク側で良きに計らってくれますので、コードにする必要はありません。

主キーとなるカラムには [Key] 属性を付けておきます。

クラスには [Table] 属性を付けてテーブル名を指定します。

インデックスやユニーク制約を付けたい場合は、クラスに [Index] 属性を付けます。インデックスを複数個作成したい場合は、[Index] 属性を複数個記述します。

複合インデックス(複数カラムで 1 つのインデックス)を作成したい場合は [Index(nameof(Name), nameof(Height))] のように 1 つの [Index] 属性の中に複数のカラムを記述します。

インデックスの詳細は EF Core のドキュメントにまとめられています。

このサンプルプログラムでは、コード記述 → コードの通りにデータベース作成、の流れですが、逆に、既にデータベースファイルがある場合は、それを解析してコードを自動生成してくれるスキャフォールディングも用意されているようです。

コンテキストクラスの作成

テーブル構造定義クラスに対応したテーブルを持つデータベースにアクセスするためには、コンテキストクラスを用います。テーブル構造定義クラスが 1 つのテーブル(のレコード)、コンテキストクラスが 1 つのデータベースファイルのイメージです。

internal class TestContext : DbContext
{
    // テストテーブル
    public DbSet<TTestData> TestData { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        SqliteConnectionStringBuilder stringBuilder = new()
        {
            DataSource = "Test.sqlite3",
        };
        using SqliteConnection sqliteConnection = new(stringBuilder.ToString());
        optionsBuilder.UseSqlite(sqliteConnection);
    }
}

テーブルを DbSet<T> のプロパティーとして宣言します。1 つのデータベースファイルに複数のテーブルがある場合は、DbSet<T> なプロパティーを複数宣言します。

OnConfiguring() でデータベースファイルと対応づけます。

データベースファイルの作成

以上 2 つのクラスを作成したことで準備は整いました。

これから、実際にデータベースを操作します。

まずは空のデータベースファイルを作成するところからですが、コンテキストクラスから EnsureCreated() するだけです。

using TestContext testContext = new();
testContext.Database.EnsureCreated();

ファイルがまだ無い場合はこれでファイルが作成され、逆に、既にデータベースが存在している場合は特に何も起こりません。データベースがクリアされたりはしませんので、とりあえず EnsureCreated() しておけばデータベースにアクセスできるようになります。

レコードの挿入

1 レコードが、初めに作成した TTestData の 1 インスタンスです。レコードの挿入はテーブルプロパティーの Add() で行います。

testContext.TestData.Add(new TTestData { Name = "Fukada Kyoko" });
testContext.TestData.Add(new TTestData { Name = "Eda Ha", Height = 159.0 });
testContext.SaveChanges();

主キーが整数の場合は自動インクリメントになりますので、Id は設定する必要ありません。Height は NULL 可なので、指定しないと NULL になります。

Add() した時点では実際にはデータベースファイルには追加されず、SaveChanges() でまとめて追加されます。

文字列で SQL を記述する必要がないため、タイプミスによるエラーが発生せず、また、Visual Studio の各種サジェストによる支援も受けられます。確実・簡単にデータベースを操作できます。

レコードの検索

レコードの検索は、テーブルプロパティーから LINQ で行います。

IQueryable<TTestData> queryResult = testContext.TestData.Where(x => x.Name == "Eda Ha" || x.Height < 150.0).OrderBy(x => x.Height);

結果は foreach で回せるので、簡単に扱えます。

検索で注意が必要なのは、文字列を「含む」検索(部分一致検索)です。大文字小文字を区別して含む検索をしたい場合(小文字の a を含む)は、String.Contains() を用いて

Where(x => x.Name.Contains("a"))

のようにします。

一方で、大文字小文字を区別せずに含む(a でも A でも含む)検索をしたい場合、

Where(x => x.Name.Contains("a", StringComparison.OrdinalIgnoreCase))

とすると、「The LINQ expression '~' could not be translated」というエラーになります(InvariantCultureIgnoreCase や CurrentCultureIgnoreCase も同様です)。代わりに、

Where(x => EF.Functions.Like(x.Name, $"%a%"))

のように Like() 関数を用います。

レコードの削除

レコードを削除する場合、削除したいレコードを検索し、それを削除する、という流れになります。

検索については前節と同様で、その結果を、RemoveRange() するだけです。

IQueryable<TTestData> queryResult = testContext.TestData.Where(x => x.Height == null || x.Height < 150.0);
testContext.TestData.RemoveRange(queryResult);
testContext.SaveChanges();

SaveChanges() をお忘れなく。

レコードの更新

レコードの削除と同様、更新したいレコードを検索し、そのプロパティーを更新する、という流れになります。

こちらも更新後の SaveChanges() をお忘れなく。

サンプルコードでは、更新の時のみ、検索結果を IQueryable<TTestData> ではなく List<TTestData> で受けています。

IQueryable で SQLite を使う場合は遅延評価されるようで、foreach 等で実際に TTestData を取得して初めて検索が行われます。大量にデータがあり途中で foreach を打ち切った場合など、後半の不要な検索が行われず効率的です。

しかし、サンプルコードの場合、身長 155 cm の人は検索対象なのできちんと 145 cm に更新されるのですが、結果表示の際は「身長 >= 150」を満たさなくなり、結果には表示されなくなってしまいます。

これを防止するために、List で検索結果を受けています。ToList() の際に検索が行われるので、後で身長が変化しても、List には引き続き対象レコードが存在することになり、きちんと結果表示も行われます。

サンプルコードについて

Runサンプルコード(Test LINQ to SQLite Gen 2)は GitHub に上げてあります。.NET 6 + Visual Studio 2022 + Windows 10 で動作確認しています。Visual Studio でソリューションを開き F5 を押せば実行できます。

本記事に対応するのは、サンプルプログラム実行時に表示されるウィンドウの左半分、「基本操作」のところです。

「検索」「削除」「更新」いずれのボタンをクリックしても、まず最初にデータベースとサンプルレコードが作成されます。削除によりレコードが 0 になっていた場合もサンプルレコードが再作成されます。

「検索」ボタンをクリックすると、名前が "Eda Ha" または、身長が 150 cm 未満の人が検索されます。

「削除」ボタンをクリックすると、身長未登録、または身長が 150 cm 未満の人が削除されます。

「更新」ボタンをクリックすると、身長 150 cm 以上の人の身長を 10 cm 下げます。

「更新」してから「検索」や「削除」すると、以前と結果が変わります。

なお、ウィンドウの右半分、「ジェネリック」については、LINQ to SQLite で共通カラム部分をジェネリックで運用するをご覧ください。

インメモリデータベース

EF Core の SQLite3 でもインメモリデータベースは使用可能です。

サンプルコードでは、TestContext.OnConfiguring() のプリプロセッサ部分を true にすることでインメモリデータベースにできます。

インメモリデータベースにする場合は、OnConfiguring() で SqliteOpenMode.Memory を用いますが、その際は接続を開いておく必要があるようです。開いておかないとエラーが出ます。

インメモリデータベースは接続が切れると消滅するので、コンテキストを MainWindow クラスのメンバとして保持し続けるなどの対応が必要になるかと思います。

ジャーナルモード

EF Core はデフォルトでジャーナルモードが WAL(Write-Ahead Logging:先行書き込みログ)になっています。

ジャーナルモードを DELETE 等他のものにしたい場合は、コマンドを実行することで可能です。

サンプルコードでは、TestContext.OnConfiguring() のプリプロセッサ部分を true にすることで DELETE にできます。ジャーナルモードを変更した場合、一度データベースファイルを削除するのが確実です。

更新履歴

  • 2022/01/01 初版。
  • 2022/01/01 ジャーナルモードについて記載。
  • 2022/01/03 インメモリデータベースについて記載。



2022 年の抱負

Store新年、明けましておめでとうございます。

昨年はカラオケ字幕動画ファイルリスト化ツール「ゆかりすたー 4 NEBULA」のバージョンアップに注力し、52 倍速という大幅な高速化を果たしました。また、Microsoft Store(ストア)での配布により、利便性も一段と向上しました。

世相としては引き続きコロナ一色の感もありましたが、ワクチン普及により対処の目処が立ちました。トヨタの中間決算が過去最高となるなど、経済も復活しつつあります。

今年は、アプリ面ではニコカラメーカー 2 のバージョンアップをしていきたいと思います。かゆいところに手が届くよう、細かなところにも気を配って開発を進めていきます。ストア配布についても、課題もあるものの状況を見ながら前向きに検討していきます。

他のアプリについて、昔開発して UI が古くなっているものについては、リニューアルできればと思っています。

技術面では、モダンな UI を実現できる WinUI3 が気になるところです。メリットや完成度を見極めながら、取り入れられるものであれば取り入れていきたいと思います。

オフライン面では、抑止していた活動を徐々に再開していくつもりです。温かく交流して頂ければ幸いです。

中期 3 ヶ年計画としては、AI や xR といったトレンドに触れていきたいというのもあります。いろんな意味での環境を整えていかないと難しいのでハードルは高いと思いますが。

それでは本年もどうぞよろしくお願いいたします。
カンパのお願い
Amazon でお買い物の際は、下記で検索して頂けたら幸いです。
記事検索
最新コメント
月別アーカイブ
  • ライブドアブログ