# 共通ドキュメント

## DataAccess

### 概要

エンティティの永続操作を実装する。

クラス名
  (システムプロジェクト名称).(サブシステム名称).(機能名称).Access.(エンティティ名称 + "Access")
namespace
  (システムプロジェクト名称).(サブシステム名称).(機能名称).Access
継承元
  N/A
インターフェース
  N/A
クラス属性
  N/A

### フィールド

以下のフィールドを定義する

- データ接続(Connectionのインスタンス)
- その他

### プロパティ

必要なプロパティを定義する。

### コンストラクタ

必要に応じてコンストラクタを定義する。

- デフォルトコンストラクタは必ず定義する。
- データ接続を新しいインスタンスで初期化しても良いが、Open()を呼び出してはならない。
- 他のデータアクセスとトランザクションを共有する場合、既に開かれたデータ接続を受け取るコンストラクタを定義する。

### メソッド

データアクセスのための操作を定義する。

##### 定義例

Insert | データの追加。戻り値として0(失敗)|1以上(成功)を返す。
Update | データの更新。戻り値として0(失敗)|1以上(成功)を返す。
Save | データの更新、追加(追加か更新か状況により変化する場合)。戻り値として0(失敗)|1以上(成功)を返す。
Delete | データの削除。戻り値として0(失敗)|1以上(成功)を返す。
Get | データの取得。戻り値として１個のエンティティを返す。
GetList | このクラスが扱うエンティティのリストを取得する場合。戻り値としてエンティティのリストを返す。
New | 新しいエンティティのインスタンスを生成する(特に他のデータにアクセスしてエンティティの初期値を取得する場合)。戻り値として１個のエンティティを返す。

##### 注意

- エンティティの種類別に操作方法が異なる場合、InsertHoge(),UpdateHoge()等のように命名する。
- 条件により取得方法が異なる場合GetByHoge()等のように命名する。

### 注意

- データ接続インスタンスは直接生成せず、ConnectionFactory#GetConnecitonByNameを使用する。
- 可能な限りログを採取する。
- 例外処理は必ず記述し、ErrorHandlerを使用してログ出力する。例外を再度送出するかは仕様による。
- 追加、更新、削除はTableAccessを使用する。またはTableAccess#BuildUpdateCommand()などで生成したTableCommandからCommandオブジェクトを取り出して実行する。
- 取得はTableAccessを使用する。またはTableAccess#BuildSelectCommand()などで生成したTableCommandからCommandオブジェクトを取り出して実行する。
- DataRowからエンティティへの展開は可能な限りAbstractTableRow#FromDataRow()を使用する。このために自力で取得クエリーを書く場合は列の別名を"(テーブル別名)__(列名)"か"(列名)"の形式とする。
- DataRowからエンティティへ自力で値をセットする時はCFW.Util.NumberUtil,CFW.Util.DateUtil,CFW.Util.StringUtilのValueメソッドを使用して値を取得する。object#ToString()は使用しない。

### サンプル

#### FXトラベル/マスタ保守/都市、地域/都市アクセスエンティティ(C#)

    namespace FxTravel.Maintainance.Area.Access
    {
        /// <summary>
        /// 都市に関するデータアクセス
        /// </summary>
        public class CityAccess
        {
            /// <summary>
            /// ログ出力
            /// </summary>
            static CFW.Log.Logger logger = CFW.Log.LoggerFactory.GetLogger(
                   "default",
                   System.Reflection.MethodBase.GetCurrentMethod().ReflectedType.FullName);

            /// <summary>
            /// CITYのプロパティ
            /// </summary>
            MstCityTableProperties cityProperties;
            /// <summary>
            /// areasのプロパティ
            /// </summary>
            MstAreasTableProperties areasProperties;
            /// <summary>
            /// countryのプロパティ
            /// </summary>
            MstCountryTableProperties countryProperties;
            /// <summary>
            /// city選択
            /// </summary>
            TableSelectCommand select ;

            /// <summary>
            /// データ接続
            /// </summary>
            Connection connection;
            /// <summary>
            /// 構築
            /// </summary>
            public CityAccess()
            {
                connection = ConnectionFactory.GetConnectionByName("default");

            }
            /// <summary>
            /// 国コードに一致する都市を取得する
            /// </summary>
            /// <param name="countryCode"></param>
            /// <returns></returns>
            public List GetListByCountry(string countryCode)
            {
                logger.Debug(MethodBase.GetCurrentMethod().Name, "start");
                try
                {
                    //返すリスト
                    List list = new List();

                    connection.Open();

                    //プロパティ生成
                    cityProperties = new MstCityTableProperties();
                    areasProperties = new MstAreasTableProperties();
                    countryProperties = new MstCountryTableProperties();
                    //コマンド準備
                    BuildSelectCommand();
                    //検索条件設定。ここでは国コード
                    select.AddWhere(new ColumnValueCondition(cityProperties.CountryCode, countryCode, "="));
                    select.AddOrderBy(cityProperties.CityCode);

                    //クエリー組み立て
                    //本当に実行するコマンド生成
                    Command command = select.GetCommand();
                    logger.Debug(MethodBase.GetCurrentMethod().Name,command.Text);//これはデバッグチェックのため

                    //コマンド実行して結果セットからエンティティ生成
                    DataSet result = connection.ExecuteQuery(command);
                    DataRowCollection rows = result.Tables[0].Rows;
                    for (int i = 0; i < rows.Count; i++)
                    {
                        DataRow row = rows[i];
                        Entity.City city = new Entity.City();
                        city.FromDataRow(row,"CITY");
                        city.AreaS.FromDataRow(row, "AREAS");
                        city.Country.FromDataRow(row, "COUNTRY");
                        list.Add(city);
                    }

                    return list;
                }
                catch (Exception ex)
                {
                    ErrorHandler handler = ErrorHandler.GetInstance(ex);
                    handler.WriteLog();
                    throw;
                }
                finally
                {
                    connection.Close();
                    logger.Debug(MethodBase.GetCurrentMethod().Name, "end");
                }
            }
            /// <summary>
            /// エリアSに一致する都市を取得する
            /// </summary>
            /// <param name="countryCode"></param>
            /// <returns></returns>
            public List GetListByAreas(string areasCode)
            {
                logger.Debug(MethodBase.GetCurrentMethod().Name, "start");
                try
                {
                    //返すリスト
                    List list = new List();

                    connection.Open();

                    //プロパティ生成
                    cityProperties = new MstCityTableProperties();
                    areasProperties = new MstAreasTableProperties();
                    countryProperties = new MstCountryTableProperties();
                    //コマンド準備
                    BuildSelectCommand();
                    //検索条件設定。ここでは国コード
                    select.AddWhere(new ColumnValueCondition(cityProperties.AreasCode, areasCode, "="));
                    select.AddOrderBy(cityProperties.CityCode);

                    //クエリー組み立て
                    //本当に実行するコマンド生成
                    Command command = select.GetCommand();
                    logger.Debug(MethodBase.GetCurrentMethod().Name, command.Text);//これはデバッグチェックのため

                    //コマンド実行して結果セットからエンティティ生成
                    DataSet result = connection.ExecuteQuery(command);
                    DataRowCollection rows = result.Tables[0].Rows;
                    for (int i = 0; i < rows.Count; i++)
                    {
                        DataRow row = rows[i];
                        Entity.City city = new Entity.City();
                        city.FromDataRow(row, "CITY");
                        city.AreaS.FromDataRow(row, "AREAS");
                        city.Country.FromDataRow(row, "COUNTRY");
                        list.Add(city);
                    }

                    return list;
                }
                catch (Exception ex)
                {
                    ErrorHandler handler = ErrorHandler.GetInstance(ex);
                    handler.WriteLog();
                    throw;
                }
                finally
                {
                    connection.Close();
                    logger.Debug(MethodBase.GetCurrentMethod().Name, "end");
                }
            }
            /// <summary>
            /// 国コードに一致する都市を取得する
            /// </summary>
            /// <param name="countryCode"></param>
            /// <returns></returns>
            public Entity.City Get(string cityCode)
            {
                logger.Debug(MethodBase.GetCurrentMethod().Name, "start");
                try
                {

                    connection.Open();

                    //プロパティ生成
                    cityProperties = new MstCityTableProperties();
                    areasProperties = new MstAreasTableProperties();
                    countryProperties = new MstCountryTableProperties();
                    //コマンド準備
                    BuildSelectCommand();
                    //検索条件設定。ここでは国コード
                    select.AddWhere(new ColumnValueCondition(cityProperties.CityCode, cityCode, "="));
                    select.AddOrderBy(cityProperties.CityCode);

                    //クエリー組み立て
                    //本当に実行するコマンド生成
                    Command command = select.GetCommand();
                    logger.Debug(MethodBase.GetCurrentMethod().Name, command.Text);//これはデバッグチェックのため

                    //コマンド実行して結果セットからエンティティ生成
                    DataSet result = connection.ExecuteQuery(command);
                    DataRowCollection rows = result.Tables[0].Rows;
                    if (rows.Count == 0) return null;

                    DataRow row = rows[0];
                    Entity.City city = new Entity.City();
                    city.FromDataRow(row, "CITY");
                    city.AreaS.FromDataRow(row, "AREAS");
                    city.Country.FromDataRow(row, "COUNTRY");
                    city.IsNew= false;// not modified
                    return city;
                }
                catch (Exception ex)
                {
                    ErrorHandler handler = ErrorHandler.GetInstance(ex);
                    handler.WriteLog();
                    throw;
                }
                finally
                {
                    connection.Close();
                    logger.Debug(MethodBase.GetCurrentMethod().Name, "end");
                }
            }
            public int Save(City.Entity.City city)
            {
                logger.Debug(MethodBase.GetCurrentMethod().Name, "start");
                try
                {
                    int result = 0;
                    connection.Open();

                    //プロパティ生成
                    cityProperties = new MstCityTableProperties();

                    MstCityTableAccess access = new MstCityTableAccess(connection,cityProperties);

                    if (city.IsDeleted)
                    {
                        result = access.Delete(city);
                        city.IsNew = true;
                    }
                    else if (city.IsModified)
                    {
                        if (city.IsNew)
                        {
                            if (access.Exists(city))
                            {
                                result = access.Update(city);
                            }
                            else
                            {
                                result = access.Insert(city);
                            }
                        }
                        else
                        {
                            result = access.Update(city);
                        }
                        city.IsNew = false;
                        city.IsModified = false;
                    }

                    return result;
                }
                catch (Exception ex)
                {
                    ErrorHandler handler = ErrorHandler.GetInstance(ex);
                    handler.WriteLog();
                    throw;
                }
                finally
                {
                    connection.Close();
                    logger.Debug(MethodBase.GetCurrentMethod().Name, "end");
                }

            }
            public int Delete(City.Entity.City city)
            {
                logger.Debug(MethodBase.GetCurrentMethod().Name, "start");
                try
                {
                    int result = 0;
                    connection.Open();

                    //プロパティ生成
                    cityProperties = new MstCityTableProperties();

                    MstCityTableAccess access = new MstCityTableAccess(connection, cityProperties);
                    result = access.Delete(city);

                    return result;
                }
                catch (Exception ex)
                {
                    ErrorHandler handler = ErrorHandler.GetInstance(ex);
                    handler.WriteLog();
                    throw;
                }
                finally
                {
                    connection.Close();
                    logger.Debug(MethodBase.GetCurrentMethod().Name, "end");
                }

            }
            /// <summary>
            /// 各種選択で共通の列、選択順設定
            /// ここでは CITY - AREAS - COUNTRYのJOINテーブル用に列と選択順を設定する
            /// </summary>
            void BuildSelectCommand()
            {
                string table = @"MST_CITY CITY
    LEFT JOIN MST_AREAS AREAS  ON CITY.AREAS_CODE = AREAS.AREAS_CODE
    LEFT JOIN MST_COUNTRY COUNTRY
    ON CITY.COUNTRY_CODE = COUNTRY.COUNTRY_CODE";
                cityProperties.SetAlias("CITY");
                areasProperties.SetAlias("AREAS");
                countryProperties.SetAlias("COUNTRY");

                select = new TableSelectCommand(table);

                cityProperties.SetAllSelectTo(ref select);

                select.AddSelect(areasProperties.AreasCode);
                select.AddSelect(areasProperties.JpnName);
                select.AddSelect(areasProperties.EngName);

                select.AddSelect(countryProperties.CountryCode);
                select.AddSelect(countryProperties.JpnName);
                select.AddSelect(countryProperties.EngName);

            }

        }
    }