Exemple #1
0
        /// <summary>
        /// コンストラクタ、親ノード、挿入先テーブルと列の並びを指定して初期化する
        /// </summary>
        /// <param name="parent">親ノード</param>
        /// <param name="table">挿入先テーブル</param>
        /// <param name="columnsExpression">列と設定値を指定する t => new[] { t.A == a, t.B == b } の様な式</param>
        public InsertInto(IQueryNode parent, TableDef <TColumns> table, Expression <Func <TColumns, bool[]> > columnsExpression)
        {
            this.Parent = parent;

            // new [] { bool, bool... } の様な形式以外はエラーとする
            var body = columnsExpression.Body;

            if (body.NodeType != ExpressionType.NewArrayInit)
            {
                throw new ApplicationException();
            }

            // 登録
            var owner = this.Owner;

            owner.RegisterTable(table);

            // bool[] の各要素初期化式を取得する
            var newexpr     = body as NewArrayExpression;
            var expressions = newexpr.Expressions;
            var map         = new Dictionary <Expression, object> {
                { columnsExpression.Parameters[0], table.Columns }
            };
            var availableColumns = owner.AllColumns;
            var tableColumnMap   = table.ColumnMap;
            var columnsOrder     = new ColumnMap();
            var values           = new ElementCode[expressions.Count];

            for (int i = 0; i < values.Length; i++)
            {
                // t.A == a の様に Equal を代入として扱いたいのでそれ以外はエラーとする
                var expression = expressions[i];
                if (expression.NodeType != ExpressionType.Equal)
                {
                    throw new ApplicationException();
                }

                var binary = expression as BinaryExpression;

                // 左辺は代入先の列でなければならない
                var left   = new ElementCode(ParameterReplacer.Replace(binary.Left, map), tableColumnMap);
                var column = left.FindColumns().FirstOrDefault();
                if (column == null)
                {
                    throw new ApplicationException();
                }

                // 右辺は式
                values[i] = new ElementCode(ParameterReplacer.Replace(binary.Right, map), availableColumns);

                // 列の生成元を右辺の式にして列を登録
                columnsOrder.Add(column);
            }

            this.Table     = table;
            this.ColumnMap = columnsOrder;
            this.ValueNode = new ValueSetter(this, columnsOrder, values);
        }