developer's diary

最近はc#のエントリが多いです

C# (dotnetcore) Microsoft.Data.Sqlite と System.Data.SQLite を利用してみる

NuGetでSystem.Data.SQLite.Coreを検索するとMicrosoft.Data.Sqlite と System.Data.SQLiteが現れた

f:id:mitsugi-bb:20200901232834p:plain
System.Data.SQLite.CoreをNuGetで検索

Download数をみると、Microsoft.Data.Sqliteの方が圧倒的に多い。

どっち使えばいいんだろ?

ということでどっちも利用してみた。

Microsoft.Data.Sqlite.Coreだけでは動かない

Microsoft.Data.Sqlite.Coreだけだと、Open時にNullReferenceExceptionが発生します。

f:id:mitsugi-bb:20200901233430p:plain
System.NullReferenceExceptionが発生

f:id:mitsugi-bb:20200901233543p:plain
Object reference not set to an instance of an object.

Microsoft.Data.Sqlite.Coreを利用するには

SQLitePCLRaw.bundle_e_sqlite3をNugetでInstallしてください。

f:id:mitsugi-bb:20200901234148p:plain
SQLitePCLRaw.bundle_e_sqlite3

SQLitePCLRaw.bundle_green でも動きます。(こっちの方がダウンロード数が多い)

Microsoft.Data.Sqliteを利用したサンプル

        /// <summary>
        /// Microsoft.Data.Sqlite + SQLitePCLRaw.bundle_e_sqlite3
        /// </summary>
        private static void MicrosoftDataSqliteExample()
        {

            //データベースに繋ぐ
            using (var connection = new Microsoft.Data.Sqlite.SqliteConnection("Data Source=mdss.db"))
            {
                //データベースをオープンする
                connection.Open();

                //テーブル削除
                using (var cmd = connection.CreateCommand())
                {
                    cmd.CommandText = "DROP TABLE IF EXISTS [TEST]";
                    cmd.ExecuteNonQuery();
                }

                //テーブル作成
                using (var cmd = connection.CreateCommand())
                {
                    cmd.CommandText = "CREATE TABLE IF NOT EXISTS [TEST](" +
                                      "[id] INTEGER PRIMARY KEY," +
                                      "[name] TEXT NOT NULL" +
                                      ")";
                    cmd.ExecuteNonQuery();
                }

                //データ削除
                using (var cmd = connection.CreateCommand())
                {
                    cmd.CommandType = System.Data.CommandType.Text;
                    cmd.CommandText = "DELETE FROM [TEST]";
                    cmd.ExecuteNonQuery();
                }

                //INSERT(1)
                using (var cmd = connection.CreateCommand())
                {
                    cmd.CommandText = "INSERT INTO [TEST]([name]) VALUES (@name)";
                    cmd.Parameters.Add(new Microsoft.Data.Sqlite.SqliteParameter() { ParameterName = "@name", Value = "TEST" });
                    cmd.ExecuteNonQuery();
                }

                //INSERT(2)※ロールバック
                var transaction = connection.BeginTransaction();
                using (var cmd = connection.CreateCommand())
                {
                    cmd.Transaction = transaction;
                    cmd.CommandText = "INSERT INTO [TEST]([name]) VALUES (@name)";
                    cmd.Parameters.Add("@name", Microsoft.Data.Sqlite.SqliteType.Text);
                    cmd.Parameters[0].Value = "rollbackData";
                    cmd.ExecuteNonQuery();
                }
                transaction.Rollback();

                //INSERT(2)
                using (var cmd = connection.CreateCommand())
                {
                    cmd.CommandText = "INSERT INTO [TEST]([name]) VALUES (@name)";
                    cmd.Parameters.Add("@name", Microsoft.Data.Sqlite.SqliteType.Text);
                    cmd.Parameters[0].Value = "name";
                    cmd.ExecuteNonQuery();
                }

                //INSERT(3)
                using (var cmd = connection.CreateCommand())
                {
                    cmd.CommandText = "INSERT INTO [TEST]([name]) VALUES (@name)";
                    cmd.Parameters.Add("@name", Microsoft.Data.Sqlite.SqliteType.Text, 1);
                    cmd.Parameters[0].Value = "example";
                    cmd.ExecuteNonQuery();
                }

                //INSERT(4)
                using (var cmd = connection.CreateCommand())
                {
                    cmd.CommandText = "INSERT INTO [TEST]([name]) VALUES (@name)";
                    cmd.Parameters.Add("@name", Microsoft.Data.Sqlite.SqliteType.Text, 10, "name");
                    cmd.Parameters[0].Value = "sqlite example";
                    cmd.ExecuteNonQuery();
                }

                //SELECT
                using (var cmd = connection.CreateCommand())
                {
                    cmd.CommandText = "SELECT [id],[name] FROM [TEST]";
                    var dataReader = cmd.ExecuteReader();
                    while (dataReader.Read())
                    {
                        long id = (long)dataReader["id"];
                        string name = (string)dataReader["name"];
                        Console.Write(id);
                        Console.Write(",");
                        Console.WriteLine(name);
                    }
                }
            }
        }

System.Data.SQLite を利用したサンプル

Microsoft.Data.Sqliteとの違いは、

connectionの生成部分と、パラメータの型(System.Data.DbType.String)だけです。

それ以外は全て同じです。

        /// <summary>
        /// System.Data.SQLite
        /// </summary>
        private static void SystemDataSQLiteExample()
        {
            //データベースに繋ぐ
            using (var connection = new System.Data.SQLite.SQLiteConnection("Data Source=sdss.db"))
            {
                //データベースをオープンする
                connection.Open();

                //テーブル削除
                using (var cmd = connection.CreateCommand())
                {
                    cmd.CommandText = "DROP TABLE IF EXISTS [TEST]";
                    cmd.ExecuteNonQuery();
                }

                //データベースをオープンする
                using (var cmd = connection.CreateCommand())
                {
                    cmd.CommandText = "CREATE TABLE IF NOT EXISTS [TEST](" +
                                      "[id] INTEGER PRIMARY KEY," +
                                      "[name] TEXT NOT NULL" +
                                      ")";
                    cmd.ExecuteNonQuery();
                }

                //データ削除
                using (var cmd = connection.CreateCommand())
                {
                    cmd.CommandType = System.Data.CommandType.Text;
                    cmd.CommandText = "DELETE FROM [TEST]";
                    cmd.ExecuteNonQuery();
                }

                //INSERT(1)
                using (var cmd = connection.CreateCommand())
                {
                    cmd.CommandText = "INSERT INTO [TEST]([name]) VALUES (@name)";
                    cmd.Parameters.Add(new System.Data.SQLite.SQLiteParameter() { ParameterName = "@name", Value = "TEST" });
                    cmd.ExecuteNonQuery();
                }

                //INSERT(2)※ロールバック
                var transaction = connection.BeginTransaction();
                using (var cmd = connection.CreateCommand())
                {
                    cmd.Transaction = transaction;
                    cmd.CommandText = "INSERT INTO [TEST]([name]) VALUES (@name)";
                    cmd.Parameters.Add("@name", System.Data.DbType.String);
                    cmd.Parameters[0].Value = "rollbackData";
                    cmd.ExecuteNonQuery();
                }
                transaction.Rollback();

                //INSERT(2)
                using (var cmd = connection.CreateCommand())
                {
                    cmd.CommandText = "INSERT INTO [TEST]([name]) VALUES (@name)";
                    cmd.Parameters.Add("@name", System.Data.DbType.String);
                    cmd.Parameters[0].Value = "name";
                    cmd.ExecuteNonQuery();
                }

                //INSERT(3)
                using (var cmd = connection.CreateCommand())
                {
                    cmd.CommandText = "INSERT INTO [TEST]([name]) VALUES (@name)";
                    cmd.Parameters.Add("@name", System.Data.DbType.String, 1);
                    cmd.Parameters[0].Value = "example";
                    cmd.ExecuteNonQuery();
                }

                //INSERT(4)
                using (var cmd = connection.CreateCommand())
                {
                    cmd.CommandText = "INSERT INTO [TEST]([name]) VALUES (@name)";
                    cmd.Parameters.Add("@name", System.Data.DbType.String, 10, "name");
                    cmd.Parameters[0].Value = "sqlite example";
                    cmd.ExecuteNonQuery();
                }

                //SELECT
                using (var cmd = connection.CreateCommand())
                {
                    cmd.CommandText = "SELECT [id],[name] FROM [TEST]";
                    var dataReader = cmd.ExecuteReader();
                    while (dataReader.Read())
                    {
                        long id = (long)dataReader["id"];
                        string name = (string)dataReader["name"];
                        Console.Write(id);
                        Console.Write(",");
                        Console.WriteLine(name);
                    }
                }
            }
        }

動かしてみよう!

        private static void Main(string[] args)
        {
            //Microsoft.Data.Sqlite + SQLitePCLRaw.bundle_e_sqlite3
            Console.WriteLine("Microsoft.Data.Sqlite");
            MicrosoftDataSqliteExample();

            //System.Data.SQLite
            Console.WriteLine("System.Data.SQLite");
            SystemDataSQLiteExample();
        }

結果

f:id:mitsugi-bb:20200901235615p:plain
実行結果

違いは、パラメータで指定したサイズが有効になっているか、無視されているかの違いです。

Microsoft.Data.Sqliteの方が厳密に動いている気もします。

Native SQLite Managerで開いてみる

App Storeでインストールした、 Native SQLite Managerで開いてみました。

問題なく両方開くことができました。

Microsoft.Data.Sqliteバージョン f:id:mitsugi-bb:20200902000138p:plain

System.Data.SQLiteバージョン f:id:mitsugi-bb:20200902000155p:plain

以上!

参考

stackoverflow.com