Accessにシリアライズ可能なTextBox, ComboBox, ListBox

シリアライズというと、XMLのような気もしますが、
VB6からAccessに慣れ親しんだおいらには、Accessに設定保存してみたいと思えます。

そこで!作ってみました。

まずは、アクセス保存可能インターフェース:IAccessSavable

namespace MyDummySQL.AccessSavables
{
    interface IAccessSavable
    {
        string Ext { get; set; }
        void Save(DAOContext con, string header);
        void Load(DAOContext con, string header);
        void SetExt(string ext_);
    }
}


インターフェースを継承したTextBox:AccessSavableTextBox

namespace MyDummySQL.AccessSavables
{
    public class AccessSavableTextBox : TextBox, IAccessSavable
    {
        public string Ext { get; set; }

        public AccessSavableTextBox() : base() 
        {
            this.Ext = "ext";
        }

        public void Save(DAOContext con, string header)
        {
            string saveText = this.Text;
            if (char.IsLetter(this.PasswordChar) )
            {
                //暗号化
                saveText = CryptHelper.EncryptString(saveText, CryptHelper.cryptseed);
            }

            MyDummySQLSettingsSingleton.setValue(con, header, "KEY_" + this.Ext.ToUpper() + "_" + this.Name.ToUpper(), this.Text);
        }
        public void Load(DAOContext con, string header)
        {
            string loadText = MyDummySQLSettingsSingleton.getStringValue(con, header, "KEY_" + this.Ext.ToUpper() + "_"  + this.Name.ToUpper());

            if (char.IsLetter(this.PasswordChar) )
            {
                //暗号化
                loadText = CryptHelper.DecryptString(loadText, CryptHelper.cryptseed);
            }

            this.Text = loadText;

        }
        public void SetExt(string ext_)
        {
            this.Ext = ext_;
        }
    }
}


インターフェースを継承したComboBox: AccessSavableComboBox

namespace MyDummySQL.AccessSavables
{
    public class AccessSavableComboBox : ComboBox, IAccessSavable
    {
        public string Ext { get; set; }

        public AccessSavableComboBox()
            : base()
        {
            this.Ext = "ext";
        }

        public void Save(DAOContext con, string header)
        {
            string key = "KEY_" + this.Ext.ToUpper() + "_" + this.Name.ToUpper();
            string idxkey = "KEY_" + this.Ext.ToUpper() + "_IDX_" + this.Name.ToUpper();
            
            int idx = this.SelectedIndex;

            //delete
            MyDummySQLSettingsSingleton.deleteSettings(con, header, key);
            MyDummySQLSettingsSingleton.deleteSettings(con, header, idxkey);

            //set
            List strs = new List();

            foreach (object o in this.Items)
            {
                strs.Add(o.ToString());
            }
            MyDummySQLSettingsSingleton.setStringValues(con, header, key, strs);

            //save idx
            MyDummySQLSettingsSingleton.setValue(con, header, key, idx);
        }

        public void Load(DAOContext con, string header)
        {
            this.Items.Clear();
            string key = "KEY_" + this.Ext.ToUpper() + "_" + this.Name.ToUpper();
            string idxkey = "KEY_" + this.Ext.ToUpper() + "_IDX_" + this.Name.ToUpper();

            //load
            this.Items.AddRange(MyDummySQLSettingsSingleton.getStringValues(con, header, key).ToArray());

            //load idx
            int idx = 0;
            MyDummySQLSettingsSingleton.getValue(con, header, key, out idx);
            if (this.Items.Count > idx)
            {
                this.SelectedIndex = idx;
            }

        }

        public void SetExt(string ext_)
        {
            this.Ext = ext_;
        }

    }
}

インターフェースを継承したComboBox: AccessSavableListBox

namespace MyDummySQL.AccessSavables
{
    public class AccessSavableListBox : ListBox, IAccessSavable
    {
        public string Ext { get; set; }

        public AccessSavableListBox() : base() 
        {
            this.Ext = "ext";
        }

        public void Save(DAOContext con, string header)
        {
            string key = "KEY_" + this.Ext.ToUpper() + "_" + this.Name.ToUpper();
            string idxkey = "KEY_" + this.Ext.ToUpper() + "_IDX_" + this.Name.ToUpper();

            int idx = this.SelectedIndex;

            //delete
            MyDummySQLSettingsSingleton.deleteSettings(con, header, key);
            MyDummySQLSettingsSingleton.deleteSettings(con, header, idxkey);

            //set
            List strs = new List();
            
            foreach (object o in this.Items)
            {
                strs.Add(o.ToString());
            }
            MyDummySQLSettingsSingleton.setStringValues(con, header, key, strs);

            //save idx
            MyDummySQLSettingsSingleton.setValue(con, header, key, idx);
        }

        public void Load(DAOContext con, string header)
        {
            this.Items.Clear();
            string key = "KEY_" + this.Ext.ToUpper() + "_" + this.Name.ToUpper();
            string idxkey = "KEY_" + this.Ext.ToUpper() + "_IDX_" + this.Name.ToUpper();

            //load
            this.Items.AddRange(MyDummySQLSettingsSingleton.getStringValues(con, header, key).ToArray());

            //load idx
            int idx = 0;
            MyDummySQLSettingsSingleton.getValue(con, header, key, out idx);
            if (this.Items.Count > idx)
            {
                this.SelectedIndex = idx;
            }

        }

        public void SetExt(string ext_)
        {
            this.Ext = ext_;
        }

    }
}


Accessに設定を保存するヘルパーシングルトン:MyDummySQLSettingsSingleton

namespace MyDummySQL.DAOs
{
   public class MyDummySQLSettingsSingleton
    {

        #region //定数
        public static string TRUE = "true";
        public static string FALSE = "false";
        #endregion

        public class values
        {
            public int intValue = 0;
            public string strgValue = "";
            public values(int intvalue, string strgvalue)
            {
                this.intValue = intvalue;
                this.strgValue = strgvalue;
            }
        }

        private static MyDummySQLSettingsSingleton sigleton_ = new MyDummySQLSettingsSingleton();

        MyDummySQLSettingsSingleton()
        {
        }

        public MyDummySQLSettingsSingleton getInstance()
        {
            return MyDummySQLSettingsSingleton.sigleton_;
        }



        public static IList getHeaderTexts()
        {
            List headertexts = new List();
            DataTable tbl = null;
            //DBから読み込む
            using (DAOContext con = new DAOContext(AccessConstring.SettingConString))
            {
                con.OpenConnection();
                MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);

                tbl = dao.selectHeaders();

                con.CloseConnection();
            }

            if (tbl != null)
            {
                foreach (DataRow row in tbl.Rows)
                {
                    headertexts.Add(row["HEADERTEXT"].ToString());
                }
            }
            return headertexts;
        }
        public static IList getHeaderTexts(DAOContext con)
        {
            List headertexts = new List();
            DataTable tbl = null;
            //DBから読み込む
            MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);

            tbl = dao.selectHeaders();

            if (tbl != null)
            {
                foreach (DataRow row in tbl.Rows)
                {
                    headertexts.Add(row["HEADERTEXT"].ToString());
                }
            }
            return headertexts;
        }

        public static void deleteSettings(string headerText)
        {

            //DBから読み込む
            using (DAOContext con = new DAOContext(AccessConstring.SettingConString))
            {
                con.OpenConnection();
                MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);

                dao.deleteSettings(headerText);
                dao.deleteHeader(headerText);

                con.CloseConnection();


            }
        }
        public static void deleteSettings(DAOContext con, string headerText)
        {

            //DBから読み込む
            MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);

            dao.deleteSettings(headerText);
            dao.deleteHeader(headerText);

        }
        public static void getValue(string headerText, string strgKey, out int intValue)
        {
            intValue = 0;

            //DBから読み込む
            using (DAOContext con = new DAOContext(AccessConstring.SettingConString))
            {
                con.OpenConnection();
                MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);

                dao.selectSetting(headerText, strgKey, out intValue);

                con.CloseConnection();


            }
        }
        public static void getValue(DAOContext con, string headerText, string strgKey, out int intValue)
        {
            intValue = 0;
            if (con.Connection.State != ConnectionState.Open) return;


            //DBから読み込む
            MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);

            dao.selectSetting(headerText, strgKey, out intValue);

        }
        public static string getStringValue(string headerText, string strgKey)
        {
            string strgValue = "";

            //DBから読み込む
            using (DAOContext con = new DAOContext(AccessConstring.SettingConString))
            {
                con.OpenConnection();
                MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);

                dao.selectSetting(headerText, strgKey, out strgValue);

                con.CloseConnection();

            }
            return strgValue;
        }
        public static string getStringValue(DAOContext con, string headerText, string strgKey)
        {
            string strgValue = "";
            if (con.Connection.State != ConnectionState.Open) return "";

            //DBから読み込む
            MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);

            dao.selectSetting(headerText, strgKey, out strgValue);

            return strgValue;
        }
        public static IList getStringValues(string headerText, string strgKey)
        {
            List ret = new List();
            DataTable tbl = null;

            //DBから読み込む
            using (DAOContext con = new DAOContext(AccessConstring.SettingConString))
            {
                con.OpenConnection();
                MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);

                tbl = dao.selectSettingRows(headerText, strgKey);

                con.CloseConnection();

            }

            if (tbl != null)
            {
                foreach (DataRow row in tbl.Rows)
                {
                    ret.Add(row["TEXTVALUE"].ToString());
                }
            }

            return ret;
        }
        public static IList getStringValues(DAOContext con, string headerText, string strgKey)
        {
            List ret = new List();
            DataTable tbl = null;

            if (con.Connection.State != ConnectionState.Open) return ret;

            //DBから読み込む
            MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);

            tbl = dao.selectSettingRows(headerText, strgKey);

            if (tbl != null)
            {
                foreach (DataRow row in tbl.Rows)
                {
                    ret.Add(row["TEXTVALUE"].ToString());
                }
            }

            return ret;
        }

        public static void setStringValues(string headerText, string strgKey, IList strgs)
        {
            int no = 1;
            using (DAOContext con = new DAOContext(AccessConstring.SettingConString))
            {
                con.OpenConnection();
                MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);

                dao.deleteSettings(headerText, strgKey);

                foreach (string strg in strgs)
                {
                    dao.insertNew(headerText, strgKey, no, strg);
                    no++;
                }

                con.CloseConnection();
            }

        }
        public static void setStringValues(DAOContext con, string headerText, string strgKey, IList strgs)
        {
            if (con.Connection.State != ConnectionState.Open) return;
            int no = 1;
            MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);

            dao.deleteSettings(headerText, strgKey);

            foreach (string strg in strgs)
            {
                dao.insertNew(headerText, strgKey, no, strg);
                no++;
            }
        }

        public static void setValue(string headerText, string strgKey, int intValue)
        {
            using (DAOContext con = new DAOContext(AccessConstring.SettingConString))
            {
                con.OpenConnection();
                MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);
                dao.mergeSettings(headerText, strgKey, intValue);
                con.CloseConnection();
            }

        }
        public static void setValue(DAOContext con, string headerText, string strgKey, int intValue)
        {
            if (con.Connection.State != ConnectionState.Open) return;
            MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);
            dao.mergeSettings(headerText, strgKey, intValue);
        }
        public static void setValue(string headerText, string strgKey, string strgValue)
        {
            using (DAOContext con = new DAOContext(AccessConstring.SettingConString))
            {
                con.OpenConnection();
                MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);
                dao.mergeSettings(headerText, strgKey, strgValue);
                con.CloseConnection();
            }
        }
        public static void setValue(DAOContext con, string headerText, string strgKey, string strgValue)
        {
            if (con.Connection.State != ConnectionState.Open) return;
            MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);
            dao.mergeSettings(headerText, strgKey, strgValue);
        }

        public static bool isExistsHeader(string headerText)
        {
            bool ret = false;
            using (DAOContext con = new DAOContext(AccessConstring.SettingConString))
            {
                con.OpenConnection();
                MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);
                ret = dao.isExistsHeader(headerText);
                con.CloseConnection();
            }
            return ret;
        }
        public static bool isExistsHeader(DAOContext con, string headerText)
        {
            if (con.Connection.State != ConnectionState.Open) return false;
            bool ret = false;
            MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);
            ret = dao.isExistsHeader(headerText);
            return ret;
        }
        public static void MergeHeader(string headerText)
        {
            using (DAOContext con = new DAOContext(AccessConstring.SettingConString))
            {
                con.OpenConnection();
                MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);
                dao.mergeHeader(headerText);
                con.CloseConnection();
            }
        }
        public static void MergeHeader(DAOContext con, string headerText)
        {
            if (con.Connection.State != ConnectionState.Open) return;
            MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);
            dao.mergeHeader(headerText);
        }
        public static void deleteSettings(string headerText, string strgKey)
        {
            using (DAOContext con = new DAOContext(AccessConstring.SettingConString))
            {
                con.OpenConnection();
                MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);
                dao.deleteSettings(headerText, strgKey);
                con.CloseConnection();
            }
        }
        public static void deleteSettings(DAOContext con, string headerText, string strgKey)
        {
            if (con.Connection.State != ConnectionState.Open) return;
            MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);
            dao.deleteSettings(headerText, strgKey);
        }
    }
}

Accessに設定を保存するDAO:MyDummySQLSettingsDAO

namespace MyDummySQL.DAOs
{
    class MyDummySQLSettingsDAO : MyDAOBase
    {
        public MyDummySQLSettingsDAO(DAOContext con) : base(con) { }

        #region //SELECT
        public void selectSetting(string headerText, string strgKey, out int intValue)
        {
            string sql = @"select *
                            from settings
                            where
                                SETTINGKEY like @pkey
                            and HEADERTEXT like @pheader";

            this.ClearParameters();
            this.AddParameter("pkey", DbType.String, strgKey);
            this.AddParameter("pheader", DbType.String, headerText);

            DataTable tbl = base.GetTable(sql);

            if (tbl.Rows.Count > 0)
            {
                int ret = 0;
                int.TryParse(tbl.Rows[0]["INTVALUE"].ToString(), out ret);
                intValue = ret;
            }
            else
            {
                intValue = 0;
            }
        }

        public DataRow selectSetting1Row(string headerText, string strgKey)
        {
            string sql = @"select *
                            from settings
                            where
                                SETTINGKEY like @pkey
                            and HEADERTEXT like @pheader";

            this.ClearParameters();
            this.AddParameter("pkey", DbType.String, strgKey);
            this.AddParameter("pheader", DbType.String, headerText);

            DataTable tbl = base.GetTable(sql);

            if (tbl.Rows.Count > 0)
            {
                return tbl.Rows[0];
            }
            else
            {
                return null;
            }
        }
        public DataTable selectSettingRows(string headeText, string strgKey)
        {
            string sql = @"select *
                            from settings
                            where
                                SETTINGKEY like @pkey
                            and HEADERTEXT like @pheader
                            order by NO1
                            ";

            this.ClearParameters();
            this.AddParameter("pkey", DbType.String, strgKey);
            this.AddParameter("pheader", DbType.String, headeText);

            return  base.GetTable(sql);

        }

        public void selectSetting(string headerText, string strgKey, out string strgValue)
        {
            string sql = @"select *
                            from settings
                            where
                                SETTINGKEY like @pkey
                            and HEADERTEXT like @pheader";

            this.ClearParameters();
            this.AddParameter("pkey", DbType.String, strgKey);
            this.AddParameter("pheader", DbType.String, headerText);

            DataTable tbl = base.GetTable(sql);

            if (tbl.Rows.Count > 0)
            {
                strgValue = tbl.Rows[0]["TEXTVALUE"].ToString();
            }
            else
            {
                strgValue = "";
            }
        }
        public DataTable selectHeaders()
        {
            string sql = @"select *
                            from header
                            order by HEADERTEXT
                            ";

            this.ClearParameters();

            return base.GetTable(sql);

        }

        public bool isExistSetting(string headerText, string strgKey)
        {
            string sql = @"select *
                            from settings
                            where
                                SETTINGKEY like @pkey
                            and HEADERTEXT = @pheader";

            this.ClearParameters();
            this.AddParameter("pkey", DbType.String, strgKey);
            this.AddParameter("pheader", DbType.String, headerText);

            DataTable tbl = base.GetTable(sql);

            if (tbl.Rows.Count > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        #endregion

        #region //ヘッダーマージ

        public bool isExistsHeader(string headerText)
        {
            string sql = @"select * 
                            from header
                            where
                                HEADERTEXT like @pheader
                                ";

            this.ClearParameters();
            this.AddParameter("pheader", DbType.String, headerText);

            DataTable tbl =  base.GetTable(sql);

            if (tbl.Rows.Count > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public int insertNewHeader(string headerText)
        {
            string sql = @"insert into
                            header(
                                HEADERTEXT
                            )
                            values(
                                @pheader
                            )";

            this.ClearParameters();
            this.AddParameter("pheader", DbType.String, headerText);

            return base.ExecuteNonQuery(sql);
        }

        public int mergeHeader(string headerText)
        {
            if (this.isExistsHeader(headerText))
            {
                return 0;
            }
            else
            {
                return this.insertNewHeader(headerText);
            }
        }

        #endregion


        #region //数値設定

        public int updateDate(string headerText, string strgKey, int intValue)
        {
            string sql = @"update settings
                            set
                                INTVALUE = @pintvalue
                            where
                                SETTINGKEY like @pkey
                            and HEADERTEXT like @pheader";

            this.ClearParameters();
            this.AddParameter("pintvalue", DbType.Int32, intValue);
            this.AddParameter("pkey", DbType.String, strgKey);
            this.AddParameter("pheader", DbType.String, headerText);

            return base.ExecuteNonQuery(sql);
        }

        public int insertNew(string headerText, string strgKey, int intValue)
        {
            string sql = @"insert into
                            settings(
                                HEADERTEXT
                                ,NO1
                                ,SETTINGKEY
                                ,INTVALUE
                            )
                            values(
                                @pheader
                                ,0
                                ,@pkey
                                ,@pintvalue
                            )";

            this.ClearParameters();
            this.AddParameter("pheader", DbType.String, headerText);
            this.AddParameter("pkey", DbType.String, strgKey);
            this.AddParameter("pintvalue", DbType.Int32, intValue);

            return base.ExecuteNonQuery(sql);
        }

        public int mergeSettings(string headerText, string strgKey, int intValue)
        {
            if (this.isExistSetting(headerText, strgKey))
            {
                return this.updateDate(headerText, strgKey, intValue);
            }
            else
            {
                return this.insertNew(headerText, strgKey, intValue);
            }
        }

        #endregion


        #region //数値設定(複数行)

        public int insertNew(string headerText, string strgKey, int no, int intValue)
        {
            string sql = @"insert into
                            settings(
                                HEADERTEXT
                                ,NO1
                                ,SETTINGKEY
                                ,INTVALUE
                            )
                            values(
                                @pheader
                                ,@pno
                                ,@pkey
                                ,@pintvalue
                            )";

            this.ClearParameters();
            this.AddParameter("pheader", DbType.String, headerText);
            this.AddParameter("pno", DbType.Int32, no);
            this.AddParameter("pkey", DbType.String, strgKey);
            this.AddParameter("pintvalue", DbType.Int32, intValue);

            return base.ExecuteNonQuery(sql);
        }

        #endregion


        #region //文字設定

        public int updateDate(string headerText, string strgKey, string strgValue)
        {
            string sql = @"update settings
                            set
                                TEXTVALUE = @ptextvalue
                            where
                                SETTINGKEY like @pkey
                            and HEADERTEXT like @pheader";

            this.ClearParameters();
            this.AddParameter("ptextvalue", DbType.String, strgValue);
            this.AddParameter("pkey", DbType.String, strgKey);
            this.AddParameter("pheader", DbType.String, headerText);

            return base.ExecuteNonQuery(sql);
        }

        public int insertNew(string headerText, string strgKey, string strgValue)
        {
            string sql = @"
insert into
settings(
HEADERTEXT
,NO1
,SETTINGKEY
,TEXTVALUE
)
values(
@pheader1
,0
,@pkey1
,@ptextvalue1
)";

            this.ClearParameters();
            this.AddParameter("pheader1", DbType.String, headerText);
            this.AddParameter("pkey1", DbType.String, strgKey);
            this.AddParameter("ptextvalue1", DbType.String, strgValue);

            return base.ExecuteNonQuery(sql);
        }

        public int mergeSettings(string headerText, string strgKey, string strgValue)
        {
            if (this.isExistSetting(headerText, strgKey))
            {
                return this.updateDate(headerText, strgKey, strgValue);
            }
            else
            {
                return this.insertNew(headerText, strgKey, strgValue);
            }
        }

        #endregion

        #region //文字設定(複数行)

        public int insertNew(string headerText, string strgKey, int no, string strgValue)
        {
            string sql = @"insert into
                            settings(
                                HEADERTEXT
                                ,NO1
                                ,SETTINGKEY
                                ,TEXTVALUE
                            )
                            values(
                                @pheader
                                ,@pno
                                ,@pkey
                                ,@ptextvalue
                            )";

            this.ClearParameters();
            this.AddParameter("pheader", DbType.String, headerText);
            this.AddParameter("pno", DbType.Int32, no);
            this.AddParameter("pkey", DbType.String, strgKey);
            this.AddParameter("ptextvalue", DbType.String, strgValue);

            return base.ExecuteNonQuery(sql);
        }


        #endregion

        #region //設定削除(複数行用)

        public int deleteSettings(string headerText, string strgKey)
        {
            string sql = @"delete from settings
                            where
                                SETTINGKEY like @pkey
                            and HEADERTEXT like @pheader";

            this.ClearParameters();
            this.AddParameter("pkey", DbType.String, strgKey);
            this.AddParameter("pheader", DbType.String, headerText);

            return base.ExecuteNonQuery(sql);
        }
        public int deleteSettings(string headerText)
        {
            string sql = @"delete from settings
                            where
                                HEADERTEXT like @pheader";

            this.ClearParameters();
            this.AddParameter("pheader", DbType.String, headerText);

            return base.ExecuteNonQuery(sql);
        }
        public int deleteHeader(string headerText)
        {
            string sql = @"delete from header
                            where
                                HEADERTEXT like @pheader";

            this.ClearParameters();
            this.AddParameter("pheader", DbType.String, headerText);

            return base.ExecuteNonQuery(sql);
        }
        
        #endregion

    }
}

で、実際に保存するまえに、LINQの拡張メソッドで、セーブ可能なコンポーネントをListに登録しておきます。

private List Savables = new List();

public void init()
{
            foreach (TabPage tab in this.tabCtrlScripts.TabPages)
            {
                //regist ↓タブコントロール配下のコントロールを一括登録
                this.Savables.AddRange(tab.Controls.OfType());

                //set ext
                foreach (IAccessSavable savable in tab.Controls.OfType())
                {
                    savable.Ext = this.Name.ToUpper();
                }
            }
}


で、実際のセーブとロード用メソッド。
(コネクションプーリングを前提にしています)

        public void Save(DAOContext con, string header)
        {
            foreach (IAccessSavable savable in this.Savables)
            {
                savable.Save(con, header);
            }
        }

        public void Load(DAOContext con, string header)
        {
            foreach (IAccessSavable savable in this.Savables)
            {
                savable.Load(con, header);
            }
        }

で、実際にメイン関数に書くのは、以下。
(カスタムコントロールを書いていますが、そのLoad()、Save()メソッドで、上のSave()、Load()メソッドを呼ぶという形です)

            //Load
            using (DAOContext con = new DAOContext(AccessConstring.SettingConString))
            {
                con.OpenConnection();
                this.tabCustControl1.Load(con, header);
                con.CloseConnection();
            }
            //Save
            using (DAOContext con = new DAOContext(AccessConstring.SettingConString))
            {
                con.OpenConnection();
                this.tabCustControl1.Save(con, header);
                con.CloseConnection();
            }