/// <summary> /// コンストラクタ、親ノードと列指定式を指定して初期化する /// </summary> /// <param name="parent">親ノード</param> /// <param name="columnsExpression">プロパティが列指定として扱われるクラスを生成する () => new { Name = "test", ID = 1 } の様な式</param> public Select(IQueryNode parent, Expression <Func <TColumns> > columnsExpression) { this.Parent = parent; this.ColumnMap = new ColumnMap(); this.Columns = TypeWiseCache <TColumns> .Creator(); // new 演算子でクラスを生成するもの以外はエラーとする var body = columnsExpression.Body; if (body.NodeType != ExpressionType.New) { throw new ApplicationException(); } // クラスのプロパティ数とコンストラクタ引数の数が異なるならエラーとする var newexpr = body as NewExpression; var args = newexpr.Arguments; var properties = typeof(TColumns).GetProperties(); if (args.Count != properties.Length) { throw new ApplicationException(); } // プロパティと列定義を結びつけその生成元としてコンストラクタ引数を指定する var environment = this.Owner.Environment; for (int i = 0; i < properties.Length; i++) { BindColumn(properties[i], new ElementCode(args[i], null)); } }
/// <summary> /// エイリアス用にクローンを作成する /// </summary> /// <returns>クローン</returns> public TableDef <TColumns> AliasedClone() { var c = this.MemberwiseClone() as TableDef <TColumns>; ColumnMap map; TColumns columns; c.ColumnMap = map = new ColumnMap(); c.Columns = columns = TypeWiseCache <TColumns> .Creator(); foreach (var column in this.ColumnMap) { map.Add(column.Clone(columns, c)); } return(c); }
/// <summary> /// コンストラクタ、DB接続環境とテーブル名を指定して初期化する /// </summary> /// <param name="environment">DB接続環境</param> /// <param name="name">DB上のテーブル名</param> public TableDef(DbEnvironment environment, string name) { this.Environment = environment; this.Name = name; this.ColumnMap = new ColumnMap(); // プロパティと列をバインドする Mediator.Table = this; try { this.Columns = TypeWiseCache <TColumns> .Creator(); // 全プロパティを一度呼び出す事でバインドされる AllColumnsBinder(this.Columns); } finally { Mediator.Table = null; } }
/// <summary> /// コンストラクタ、親ノードと列プロパティと設定する値の式を指定して初期化する /// </summary> /// <param name="parent">親ノード</param> /// <param name="properties">列に対応するプロパティ</param> /// <param name="values">列の値の式</param> public Select(IQueryNode parent, PropertyInfo[] properties, Expression[] values) { if (properties.Length != values.Length) { throw new ApplicationException(); } this.Parent = parent; this.ColumnMap = new ColumnMap(); this.Columns = TypeWiseCache <TColumns> .Creator(); // プロパティと列定義を結びつけその生成元としてコンストラクタ引数を指定する var environment = this.Owner.Environment; for (int i = 0; i < properties.Length; i++) { BindColumn(properties[i], new ElementCode(values[i], null)); } }
/// <summary> /// コンストラクタ、親ノードと列指定式を指定して初期化する /// </summary> /// <param name="parent">親ノード</param> /// <param name="body">生成元の式</param> public SelectFrom(IFrom parent, Expression body) { this.Parent = parent; this.From = parent; this.ColumnMap = new ColumnMap(); this.Columns = TypeWiseCache <TSelectedColumns> .Creator(); if (body.NodeType == ExpressionType.New) { // new 演算子でのクラス生成式に対応 // クラスのプロパティ数とコンストラクタ引数の数が異なるならエラーとする var newexpr = body as NewExpression; var args = newexpr.Arguments; var properties = typeof(TSelectedColumns).GetProperties(); if (args.Count != properties.Length) { throw new ApplicationException(); } // プロパティと列定義を結びつけその生成元としてコンストラクタ引数を指定する var owner = this.Owner; var environment = owner.Environment; var allColumns = owner.AllColumns; for (int i = 0; i < properties.Length; i++) { var pi = properties[i]; if (pi.PropertyType != args[i].Type) { throw new ApplicationException(); } BindColumn(pi.Name, "c" + i, environment.CreateDbTypeFromType(pi.PropertyType), 0, new ElementCode(args[i], allColumns)); } } else if (body.NodeType == ExpressionType.MemberInit) { // メンバ初期化式に対応 // クラスのプロパティ数とコンストラクタ引数の数が異なるならエラーとする var initexpr = body as MemberInitExpression; var bindings = initexpr.Bindings; // プロパティと列定義を結びつけその生成元としてコンストラクタ引数を指定する var owner = this.Owner; var environment = owner.Environment; var allColumns = owner.AllColumns; for (int i = 0; i < bindings.Count; i++) { var binding = bindings[i]; if (binding.BindingType != MemberBindingType.Assignment) { throw new ApplicationException(); } var assign = binding as MemberAssignment; var member = binding.Member; if (member.MemberType != System.Reflection.MemberTypes.Property) { throw new ApplicationException(); } var property = (PropertyInfo)member; BindColumn(property.Name, "c" + i, environment.CreateDbTypeFromType(property.PropertyType), 0, new ElementCode(assign.Expression, allColumns)); } } else { throw new ApplicationException(); } }