Back to Top

プログラムの覚書

C# classをコピーする

C#にてclassを変数のようにコピーしたいときがあります。ここでは、classをコピー(クローンの作成)出来るようにする方法を説明します。

インスタンス内のメンバを手動でコピーするか、ICloneableを実装してClone()を作成するか、2つの方法があり

また、 コピーをする際、シャローコピー (Shallow Copy) と、ディープコピー (Deep Copy) の2通りあります。

シャローコピーは、インスタンス内の参照型のメンバについては、参照先のインスタンスそのものがコピーされるのではなく、参照先を示すアドレスがコピーされます。

ディープコピーは、インスタンス内の参照型のメンバについてもインスタンスそのものがコピーされます。

ICloneable インターフェイスで、クローン生成する(基本的な使用方法です)

class CS : ICloneable {
  private int x = 100;
  public ArrayList list = new ArrayList();
  public int GetX() { return x; }
  public object Clone()                       // 必須 ICloneableのMemberwiseClone();にてコピーを行う
  {
    return MemberwiseClone();
  }
}

※参照型のメンバについては、参照先のインスタンスそのものがコピーされるのではなく、参照先を示すアドレスがコピーされます。

 

シャローコピーとディープコピー

class CS : ICloneable {
  private int x = 100;
  public ArrayList list = new ArrayList();         //参照型
  public int GetX()
  {
    return x;
  }

  public object Clone()                            // シャローコピーになります。
  {
    return MemberwiseClone();
  }

  public CS ShallowCopy()                          //シャローコピー
  {
    return (CS)this.Clone();
  }

  public CS DeepCopy()                             //ディープコピー
  {
    CS obj = (CS)this.Clone();
    obj.list = (ArrayList)this.list.Clone();       //参照型は全てインスタンスをコピーする
    return (CS)Clone();
  }
}

※ICloneable でクローン生成するとシャローコピーになります。

 

Posted in C# | Leave a reply

C# SQLServerを使用する

C#にてSQL Server を使用する方法を説明します。

using で System.Data.SqlClient を追加します。

他のDBに接続する場合もほぼ同様となります。(System.Data.Odbc、System.Data.OleDb)など

またオープンソース等も同等の関数が用意されている場合があります。

Postgre (Npgsql)、SQLite(System.Data.SQLite)、MySql(MySql.Data.MySqlClient)などライセンスには注意してください。

SQL Serverに接続

単にSQL Server に接続するだけのサンプルです。(例はD:\DB\TestDB.mdfのデータベースに接続しています)

using System;
using System.Data;
using System.Data.SqlClient;

namespace DBTest
{
    class sample
    {
        public void Connect01()
        {
            SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
            builder.DataSource = @".\SQLEXPRESS";
            builder.AttachDBFilename = @"D:\DB\TestDB.mdf";
            builder.IntegratedSecurity = true;
            builder.UserInstance = true;
            builder.MultipleActiveResultSets = true;
            String ConnectString = builder.ToString();

            SqlConnection sqlConnect = new SqlConnection();

            sqlConnect.ConnectionString = ConnectString;

            // 接続します。
            sqlConnect.Open();

            // 接続を解除します。
            sqlConnect.Close();

            sqlConnect.Dispose();
        }
    }
}

 

レコードを追加する(INSERT)

データベースにINSERTする方法です。以下の例はSqlCommandのParametersにて追加をしています。

using System;
using System.Data;
using System.Data.SqlClient;

namespace DBTest
{
    class sample
    {
        public void Connect02()
        {
            string ConnectString = @"Data Source=.\SQLEXPRESS;AttachDbFilename=D:\DB\TestDB.mdf;Integrated Security=True;MultipleActiveResultSets=True;User Instance=True";
            using (SqlConnection sqlConnect = new SqlConnection(ConnectString))
            {
                sqlConnect.Open();

                string sqlStr = "INSERT INTO Table_1 (Item1,Item2) VALUES (@Item1,@Item2)";
                using (SqlCommand command = new SqlCommand(sqlStr, sqlConnect))
                {
                    String val = "AAAAA";
                    SqlParameter p1 = new SqlParameter("@Item1", val);
                    command.Parameters.Add(p1);

                    //SqlParameterの省略追加
                    command.Parameters.Add("@Item2", SqlDbType.Char).Value = "XXXX2";

                    command.ExecuteNonQuery();
                }

                sqlConnect.Close();     //usingは省略可能
            }
        }
    }
}

※エスケープ処理には注意が必要です。Parametersが行ってますが、オープンソース等も同じとはかぎりません。

 

DataTableにレコードを読み込む

DataTableにSELECT文で指定したレコードデータを読み込む例です。

using System;
using System.Data;
using System.Data.SqlClient;

namespace DBTest
{
    class sample
    {       
        public void Connect03()
        {
            DataTable tbl = new DataTable(); 
            
            string ConnectString = @"Data Source=.\SQLEXPRESS;AttachDbFilename=D:\DB\TestDB.mdf;Integrated Security=True;MultipleActiveResultSets=True;User Instance=True";
            using (SqlConnection sqlConnect = new SqlConnection(ConnectString))
            {
                sqlConnect.Open();

                using (SqlCommand command = sqlConnect.CreateCommand())
                {
                    command.CommandText = @"SELECT * FROM Table_1";

                    SqlDataReader reader = command.ExecuteReader();
                    tbl.Load(reader);
                    reader.Close();
                }

                sqlConnect.Close();     //省略可
            }
        }
    }
}

※注意としては、データ量が大きすぎるとデータをDataTableに読み込みきれずプログラムが落ちます。

 

レコード数を取得する

SELECT のCOUNTにて レコード数を取得する例です。

using System;
using System.Data;
using System.Data.SqlClient;

namespace DBTest
{
    class sample
    {
        public void Connect04()
        {
            string ConnectString = @"Data Source=.\SQLEXPRESS;AttachDbFilename=D:\DB\TestDB.mdf;Integrated Security=True;MultipleActiveResultSets=True;User Instance=True";

            int Count;
            using (SqlConnection sqlConnect = new SqlConnection(ConnectString))
            {
                sqlConnect.Open();

                using (SqlCommand command = new SqlCommand("SELECT COUNT(*) FROM Table_1", sqlConnect))
                {
                    Count = (int)command.ExecuteScalar();
                }

                sqlConnect.Close();     //省略可
            }
        }
    }
}

 

スキーマ情報の取得

レコードフィールドの属性の取得方法の例です。

using System;
using System.Data;
using System.Data.SqlClient;

namespace DBTest
{
    class sample
    {
        public void Connect05()
        {
            string ConnectString = @"Data Source=.\SQLEXPRESS;AttachDbFilename=D:\DB\TestDB.mdf;Integrated Security=True;MultipleActiveResultSets=True;User Instance=True";

            DataTable AllTable;
            DataTable schemaTable;
            using (SqlConnection sqlConnect = new SqlConnection(ConnectString))
            {
                sqlConnect.Open();

                //全てのテーブルを取得します。
                AllTable = sqlConnect.GetSchema("Tables");

                using (SqlCommand command = sqlConnect.CreateCommand())
                {
                    command.CommandText = "SELECT * FROM Table_1";
                    SqlDataReader dtReader = command.ExecuteReader();

                    //テーブル内の列情報を取得します。
                    schemaTable = dtReader.GetSchemaTable();

                    dtReader.Close();
                }

                sqlConnect.Close();     //省略可
            }
        }
    }
}

 

トランザクション

データベースにトランザクションを行う例です。

using System;
using System.Data;
using System.Data.SqlClient;

namespace DBTest
{
    class sample
    {
        public void Connect06()
        {
            SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
            builder.DataSource = @".\SQLEXPRESS";
            builder.AttachDBFilename = @"D:\DB\TestDB.mdf";
            builder.IntegratedSecurity = true;
            builder.UserInstance = true;
            builder.MultipleActiveResultSets = true;
            String ConnectString = builder.ToString();

            using (SqlConnection sqlConnect = new SqlConnection(ConnectString))
            {
                sqlConnect.Open();

                using (SqlCommand command = sqlConnect.CreateCommand())
                {
                    //トランザクション処理を開始する
                    using (SqlTransaction tran = sqlConnect.BeginTransaction())
                    {
                        //コマンドをトランザクション処理に組み入れる
                        command.Transaction = tran;

                        try
                        {
                            command.CommandText = "UPDATE Table_1 SET Item2 = 'A0001'";
                            command.ExecuteNonQuery();

                            //コミット処理
                            tran.Commit();
                        }
                        catch (Exception ex)
                        {
                            //ロールバック処理
                            tran.Rollback();
                        }
                    }
                }

                sqlConnect.Close();     //省略可
            }
        }
    }
}