private MetaTable BuildOrGetMetaTable(ViewTable parentVTable, ViewTable buildingVTable) { if (parentVTable == null) { //no parent view table mean we are building the root table and must create a meta table. if (buildingVTable == null) { //we must be building a view table when building the root. DebugUtility.LogError("Failed to build the root view table."); MemoryProfilerAnalytics.AddMetaDatatoEvent <MemoryProfilerAnalytics.LoadViewXMLEvent>(8); } Database.MetaTable metaTable = new Database.MetaTable(); metaTable.name = name; metaTable.displayName = name; metaTable.defaultFilter = defaultFilter; metaTable.defaultAllLevelSortFilter = defaultAllLevelSortFilter; buildingVTable.m_Meta = metaTable; return(metaTable); } else { // if has a parent, use parent's meta table if (buildingVTable != null) { buildingVTable.m_Meta = parentVTable.m_Meta; } return(parentVTable.m_Meta); } }
public long GetChildCount(ViewSchema vs, ViewTable vTable, Operation.ExpressionParsingContext expressionParsingContext) { switch (type) { case DataType.Node: if (vTable.ValidChildNodeIndices != null) { return(vTable.ValidChildNodeIndices.LongLength); } else { return(child.Count); } case DataType.Select: if (vTable.dataSelectSet.IsManyToMany()) { return(0); } else { return(vTable.dataSelectSet.GetMainRowCount()); } case DataType.NoData: default: return(0); } }
public WhereUnion(List <Where.Builder> builders, ViewSchema vs, ViewTable vTable, SelectSet selectSet, Select select, Schema baseSchema, Table table, Operation.ExpressionParsingContext expressionParsingContext) { foreach (var b in builders) { Add(b.Build(vs, vTable, selectSet, select, baseSchema, table, expressionParsingContext)); } }
public bool EvaluateCondition(ViewSchema vs, ViewTable parentViewTable, Operation.ExpressionParsingContext expressionParsingContext) { if (condition == null) { return(true); } using (ScopeDebugContext.Func(() => { return("EvaluateCondition on Node '" + GetFullName() + "'"); })) { var option = new Operation.Expression.ParseIdentifierOption(vs, parentViewTable, true, true, null, expressionParsingContext); option.formatError = (string s, Operation.Expression.ParseIdentifierOption opt) => { string str = "Error while evaluating node condition."; if (vs != null) { str += " schema '" + vs.name + "'"; } if (parentViewTable != null) { str += " view table '" + parentViewTable.GetName() + "'"; } return(str + " : " + s); }; var resolvedCondition = condition.Build(option); if (resolvedCondition == null) { return(false); } return(resolvedCondition.GetValue(0)); } }
//A column under a <Node> (or <View>) element is either a declaration (build meta data only) or defines an entry in the parent's ViewColumnNode public void BuildNodeValue(ViewTable.Builder.BuildingData buildingData, ViewTable vTable, ViewTable.Builder.Node node, long row, ViewTable parentViewTable, Operation.ExpressionParsingContext expressionParsingContext, ref Database.MetaColumn metaColum) { BuildOrUpdateDeclaration(buildingData, vTable, ref metaColum, expressionParsingContext); //If the parent's node data type is Node if (node.parent != null && node.parent.data.type == ViewTable.Builder.Node.Data.DataType.Node) { // this column is an entry in the parent's column var option = new Operation.Expression.ParseIdentifierOption(buildingData.Schema, parentViewTable, true, true, metaColum != null ? metaColum.Type.scriptingType : null, expressionParsingContext); option.formatError = (string s, Operation.Expression.ParseIdentifierOption opt) => { return(FormatErrorContextInfo(buildingData.Schema, parentViewTable) + " : " + s); }; Operation.Expression expression = Operation.Expression.ParseIdentifier(value, option); //if the meta column does not have a type defined yet, define it as the expression's type. if (metaColum.Type.scriptingType == null) { DataMatchMethod matchMethod = expression.type == typeof(string) ? DataMatchMethod.AsString : DataMatchMethod.AsNumber; metaColum.Type = new MetaType() { scriptingType = expression.type, comparisonMethod = matchMethod }; } ViewColumnNode.IViewColumnNode column = BuildOrGetColumnNode(parentViewTable, metaColum, name, expressionParsingContext); column.SetEntry(row, expression, m_MetaLink); } }
static ViewColumnNode.IViewColumnNode BuildOrGetColumnNode(ViewTable vTable, Database.MetaColumn metaColumn, string columnName, Operation.ExpressionParsingContext expressionParsingContext) { var column = vTable.GetColumnByName(columnName); if (column == null) { var columnNode = (ViewColumnNode.IViewColumnNode)Operation.ColumnCreator.CreateColumn(typeof(ViewColumnNodeTyped <>), metaColumn.Type); ViewColumnNode viewColumnNode = new ViewColumnNode(vTable, metaColumn, expressionParsingContext); columnNode.SetColumn(viewColumnNode); vTable.SetColumn(metaColumn, columnNode.GetColumn()); return(columnNode); } // View table use expand column to decorate the IViewColumnNode with required functionality for expanding rows. // So we need to get the underlying column, which is the IViewColumnNode we want. if (column is IColumnDecorator) { column = (column as IColumnDecorator).GetBaseColumn(); } if (column is ViewColumnNode.IViewColumnNode) { return((ViewColumnNode.IViewColumnNode)column); } else { throw new Exception("Expecting column '" + vTable.GetName() + "." + metaColumn.Name + "' to be a from a node data type (ViewColumnNode) but is of type '" + column.GetType().Name + "'"); } }
// When building as node, the columns are interpreted as entries in the parent's view table. public void BuildAsNode(ViewTable parentViewTable, long row, ViewSchema vs, Database.Schema baseSchema, Operation.ExpressionParsingContext parentExpressionParsingContext) { MetaTable metaTable = BuildOrGetMetaTable(parentViewTable, null); if (localSelectSet.select.Count > 0) { DebugUtility.LogError("Node '" + GetFullName() + " ' cannot have any local select statement when the parent data type is 'node'. Ignoring all selects."); } //build columns foreach (var colb in column) { MetaColumn metaColumn = metaTable.GetColumnByName(colb.name); bool hadMetaColumn = metaColumn != null; colb.BuildNodeValue(this, row, vs, baseSchema, parentViewTable, parentExpressionParsingContext, ref metaColumn); // add the metacolum to the metatable if it just got created if (!hadMetaColumn) { metaTable.AddColumn(metaColumn); } } //Build missing column for (int i = 0; i != metaTable.GetColumnCount(); ++i) { var metaColumn = metaTable.GetColumnByIndex(i); if (!HasColumn(metaColumn.Name)) { ViewColumn.Builder.BuildNodeValueDefault(this, row, vs, baseSchema, parentViewTable, parentExpressionParsingContext, metaColumn); } } }
// When building as node, the columns are interpreted as entries in the parent's view table. public void BuildAsNode(BuildingData buildingData, ViewTable parentViewTable, long row, Operation.ExpressionParsingContext parentExpressionParsingContext) { MetaTable metaTable = BuildOrGetMetaTable(parentViewTable, null); if (localSelectSet.select.Count > 0) { DebugUtility.LogError("Node '" + GetFullName() + " ' cannot have any local select statement when the parent data type is 'node'. Ignoring all selects."); } //build columns foreach (var colb in column) { MetaColumn metaColumn = metaTable.GetColumnByName(colb.name); colb.BuildNodeValue(buildingData, parentViewTable, this, row, parentViewTable, parentExpressionParsingContext, ref metaColumn); } //Build missing column for (int i = 0; i != metaTable.GetColumnCount(); ++i) { var metaColumn = metaTable.GetColumnByIndex(i); if (!HasColumn(metaColumn.Name)) { ViewColumn.Builder.BuildNodeValueDefault(buildingData, this, row, parentViewTable, parentExpressionParsingContext, metaColumn); } } }
//Create a column that merge the result of all sub nodes static public Column BuildColumnNodeMerge(ViewTable vTable, Database.MetaColumn metaColumn, Operation.ExpressionParsingContext expressionParsingContext) { var columnNode = (ViewColumnNode.IViewColumnNode)Operation.ColumnCreator.CreateColumn(typeof(ViewColumnNodeMergeTyped <>), metaColumn.Type); ViewColumnNode viewColumnNode = new ViewColumnNode(vTable, metaColumn, expressionParsingContext); columnNode.SetColumn(viewColumnNode); return(columnNode.GetColumn()); }
public void Build(BuildingData buildingData, Node node, ViewTable vTable, ViewTable parent, Operation.ExpressionParsingContext parentExpressionParsingContext) { // build selects vTable.SetupDataSelectSet(dataSelectSet.Build(vTable, buildingData.Schema, buildingData.BaseSchema)); // build columns switch (type) { case Data.DataType.Node: // these column are declarations foreach (var colb in column) { MetaColumn metaColumn = buildingData.MetaTable.GetColumnByName(colb.name); colb.BuildOrUpdateDeclaration(buildingData, vTable, ref metaColumn, vTable.ExpressionParsingContext); } // for node type we need to build all child node right away as they defines the entries in this viewtable var validChildNodeIndices = new List <int>(); int iValidChild = 0; for (int iChild = 0; iChild != child.Count; ++iChild) { var c = child[iChild]; if (c.EvaluateCondition(buildingData.Schema, vTable, vTable.ExpressionParsingContext)) { validChildNodeIndices.Add(iChild); c.BuildAsNode(buildingData, vTable, (long)iValidChild, vTable.ExpressionParsingContext); ++iValidChild; } } if (iValidChild != child.Count) { vTable.ValidChildNodeIndices = validChildNodeIndices.ToArray(); } else { vTable.ValidChildNodeIndices = null; } break; case DataType.Select: // these columns are instances of ViewColumn. They have the result of select statement as entries foreach (var colb in column) { MetaColumn metaColumn = buildingData.MetaTable.GetColumnByName(colb.name); var newColumn = colb.Build(buildingData, node, vTable, vTable.ExpressionParsingContext, ref metaColumn); vTable.SetColumn(metaColumn, newColumn.GetColumn()); } break; } }
public Where Build(ViewSchema vs, ViewTable vTable, SelectSet selectSet, Select select, Schema baseSchema, Table table, Operation.ExpressionParsingContext expressionParsingContext) { Where w = new Where(); var option = new Operation.Expression.ParseIdentifierOption(vs, table, true, false, null, expressionParsingContext); option.formatError = (msg, y) => { return(FormatErrorContextInfo(vs, vTable, select) + msg); }; option.BypassSelectSetCondition = selectSet; w.m_Comparison = comparison.Build(option); return(w); }
private string FormatErrorContextInfo(ViewSchema vs, ViewTable vTable) { string str = "Error while building view column '" + name + "'"; if (vs != null) { str += " schema '" + vs.name + "'"; } if (vTable != null) { str += " view table '" + vTable.GetName() + "'"; } return(str); }
public void Build(ViewSchema vs, ViewTable vTable, SelectSet selectSet, Select sel, Database.Schema baseSchema, Operation.ExpressionParsingContext expressionParsingContext) { if (where.Count > 0) { sel.where = new WhereUnion(); foreach (var w in where) { var w2 = w.Build(vs, vTable, selectSet, sel, baseSchema, sel.sourceTable, expressionParsingContext); if (w2.Comparison.IsManyToMany()) { sel.isManyToMany = true; } sel.where.Add(w2); } } }
public SelectSet Build(ViewTable viewTable, ViewSchema viewSchema, Database.Schema baseSchema) { if (select.Count == 0) { return(null); } SelectSet selectSet = new SelectSet(); // Create select statements (first pass) foreach (var iSelect in select) { Select s = iSelect.Create(viewTable.ViewSchema, baseSchema, viewTable); if (s != null) { selectSet.Add(s); } else { DebugUtility.LogError("Could not create Select named '" + iSelect.name + "'"); } } // add current set to the expression parsing hierarchy var expressionParsingContext = new Operation.ExpressionParsingContext(viewTable.ExpressionParsingContext, selectSet); // Build select statements (second pass) var eSelBuilder = select.GetEnumerator(); var eSelList = selectSet.select.GetEnumerator(); while (eSelBuilder.MoveNext()) { eSelList.MoveNext(); eSelBuilder.Current.Build(viewSchema, viewTable, selectSet, eSelList.Current, baseSchema, expressionParsingContext); } if (Condition != null) { Operation.Expression.ParseIdentifierOption parseOpt = new Operation.Expression.ParseIdentifierOption(viewSchema, viewTable, true, false, null, expressionParsingContext); parseOpt.BypassSelectSetCondition = selectSet; selectSet.Condition = Condition.Build(parseOpt); } return(selectSet); }
private string FormatErrorContextInfo(ViewSchema vs, ViewTable vTable, Select select) { string str = ""; if (vs != null && vTable != null) { str += "Error while building view '" + vs.name + "' table '" + vTable.GetName() + "'"; } if (select != null) { str += " select '" + select.name + "'"; } if (str != "") { str += ". "; } return(str); }
public ViewTable Build(BuildingData buildingData, ViewTable parent, long row, ViewSchema vs, Database.Schema baseSchema, Operation.ExpressionParsingContext parentExpressionParsingContext) { // Check for usage error from data. if (parent == null && String.IsNullOrEmpty(name)) { DebugUtility.LogError("Table need a name"); return(null); } using (ScopeDebugContext.Func(() => { return("View '" + GetFullName() + "'"); })) { // Check for usage error from code. DebugUtility.CheckCondition(parent == null || (parent.node == this.parent), "Parent ViewTable must points to the node's parent while building child node's ViewTable."); ViewTable vTable = new ViewTable(vs, baseSchema, this, parentExpressionParsingContext); // If has local select set, create it and add it to the expression parsing context hierarchy. see [Figure.1] vTable.SetupLocalSelectSet(localSelectSet.Build(vTable, vs, baseSchema)); MetaTable metaTable = BuildOrGetMetaTable(parent, vTable); if (buildingData.MetaTable == null) { buildingData.MetaTable = metaTable; } //declare columns foreach (var colb in column) { MetaColumn metaColumn = metaTable.GetColumnByName(colb.name); colb.BuildOrUpdateDeclaration(buildingData, vTable, ref metaColumn, vTable.ExpressionParsingContext); } if (data != null) { data.Build(buildingData, this, vTable, parent, parentExpressionParsingContext); } // Fix meta columns (that does not have a data type set) to their fallback value foreach (var fb in buildingData.FallbackColumnType) { if (fb.Key.Type == null) { fb.Key.Type = fb.Value; } } //Build missing column with default behavior for (int i = 0; i != metaTable.GetColumnCount(); ++i) { var metaColumn = metaTable.GetColumnByIndex(i); var column = vTable.GetColumnByIndex(i); if (column == null) { if (metaColumn.DefaultMergeAlgorithm != null) { //when we have a merge algorithm, set the entries as the result of each group's merge value. column = ViewColumn.Builder.BuildColumnNodeMerge(vTable, metaColumn, parentExpressionParsingContext); } vTable.SetColumn(metaColumn, column); } } if (data != null && data.type == Data.DataType.Select && vTable.dataSelectSet.IsManyToMany()) { DebugUtility.LogError("Cannot build a view using a many-to-many select statement. Specify a row value for your select statement where condition(s)."); MemoryProfilerAnalytics.AddMetaDatatoEvent <MemoryProfilerAnalytics.LoadViewXMLEvent>(7); } return(vTable); } }
public IViewColumn Build(ViewTable.Builder.Node node, ViewSchema vs, Database.Schema baseSchema, ViewTable vTable, Operation.ExpressionParsingContext expressionParsingContext, ref Database.MetaColumn metaColumn) { // Check if we have a type mismatch Type columnValueType = metaColumn != null ? metaColumn.Type : null; if (value.type != null) { if (columnValueType != null && columnValueType != value.type) { DebugUtility.LogWarning("While building column '" + name + "' : " + "Cannot override type from '" + columnValueType.Name + "' to '" + value.type.Name + "'"); } columnValueType = value.type; } // Parse expression value Operation.Expression.ParseIdentifierOption parseOpt = new Operation.Expression.ParseIdentifierOption(vs, vTable, true, false, columnValueType, expressionParsingContext); parseOpt.formatError = (string s, Operation.Expression.ParseIdentifierOption opt) => { return(FormatErrorContextInfo(vs, vTable) + " : " + s); }; Operation.Expression expression = Operation.Expression.ParseIdentifier(value, parseOpt); // Build declaration with the type we've just parsed BuildOrUpdateDeclaration(ref metaColumn, expression.type); IViewColumn result = (IViewColumn)Operation.ColumnCreator.CreateViewColumnExpression(expression); ViewColumn vc = new ViewColumn(); vc.m_MetaLink = m_MetaLink; vc.viewTable = vTable; vc.ParsingContext = expressionParsingContext; result.SetColumn(vc, null); return(result); }
// Set a Node value to the merged result of it's sub entries public static void BuildNodeValueDefault(ViewTable.Builder.Node node, long row, ViewSchema vs, Database.Schema baseSchema, ViewTable parentViewTable, Operation.ExpressionParsingContext expressionParsingContext, Database.MetaColumn metaColumn) { //set the entry for merge column if (metaColumn.DefaultMergeAlgorithm != null && metaColumn.Type != null) { ViewColumnNode.IViewColumnNode column = BuildOrGetColumnNode(parentViewTable, metaColumn, metaColumn.Name, expressionParsingContext); Operation.Expression expression = Operation.ColumnCreator.CreateTypedExpressionColumnMerge(metaColumn.Type, parentViewTable, row, column.GetColumn(), metaColumn); column.SetEntry(row, expression, null); } }
//A column under a <Node> (or <View>) element is either a declaration (build meta data only) or defines an entry in the parent's ViewColumnNode public void BuildNodeValue(ViewTable.Builder.Node node, long row, ViewSchema vs, Database.Schema baseSchema, ViewTable parentViewTable, Operation.ExpressionParsingContext expressionParsingContext, ref Database.MetaColumn metaColum) { BuildOrUpdateDeclaration(ref metaColum); //If the parent's node data type is Node if (node.parent != null && node.parent.data.type == ViewTable.Builder.Node.Data.DataType.Node) { // this column is an entry in the parent's column var option = new Operation.Expression.ParseIdentifierOption(vs, parentViewTable, true, true, metaColum != null ? metaColum.Type : null, expressionParsingContext); option.formatError = (string s, Operation.Expression.ParseIdentifierOption opt) => { return(FormatErrorContextInfo(vs, parentViewTable) + " : " + s); }; Operation.Expression expression = Operation.Expression.ParseIdentifier(value, option); //if the meta column does not have a type defined yet, define it as the expression's type. if (metaColum.Type == null) { metaColum.Type = expression.type; } ViewColumnNode.IViewColumnNode column = BuildOrGetColumnNode(parentViewTable, metaColum, name, expressionParsingContext); column.SetEntry(row, expression, m_MetaLink); } }
public ViewTable Build(ViewTable parent, long row, ViewSchema vs, Database.Schema baseSchema, Operation.ExpressionParsingContext parentExpressionParsingContext) { // Check for usage error from data. if (parent == null && String.IsNullOrEmpty(name)) { DebugUtility.LogError(FormatErrorContextInfo(vs) + ": Table need a name"); return(null); } using (ScopeDebugContext.Func(() => { return("View '" + GetFullName() + "'"); })) { // Check for usage error from code. DebugUtility.CheckCondition(parent == null || (parent.node == this.parent), FormatErrorContextInfo(vs) + ": Parent ViewTable must points to the node's parent while building child node's ViewTable."); if (data == null) { //no data return(null); } ViewTable vTable = new ViewTable(vs, baseSchema); vTable.node = this; vTable.parentExpressionParsingContext = parentExpressionParsingContext; vTable.expressionParsingContext = parentExpressionParsingContext; // If has local select set, create it and add it to the expression parsing context hierarchy. see [Figure.1] vTable.localSelectSet = localSelectSet.Build(vTable, vs, baseSchema); if (vTable.localSelectSet != null) { vTable.expressionParsingContext = new Operation.ExpressionParsingContext(vTable.expressionParsingContext, vTable.localSelectSet); } MetaTable metaTable = BuildOrGetMetaTable(parent, vTable); //declare columns foreach (var colb in column) { MetaColumn metaColumn = metaTable.GetColumnByName(colb.name); bool hadMetaColumn = metaColumn != null; colb.BuildOrUpdateDeclaration(ref metaColumn); // add the metacolum to the metatable if it just got created if (!hadMetaColumn) { metaTable.AddColumn(metaColumn); } } data.Build(this, vTable, parent, vs, baseSchema, parentExpressionParsingContext, metaTable); //Build missing column with default behavior for (int i = 0; i != metaTable.GetColumnCount(); ++i) { var metaColumn = metaTable.GetColumnByIndex(i); var column = vTable.GetColumnByIndex(i); if (column == null) { if (metaColumn.DefaultMergeAlgorithm != null) { //when we have a merge algorithm, set the entries as the result of each group's merge value. column = ViewColumn.Builder.BuildColumnNodeMerge(vTable, metaColumn, parentExpressionParsingContext); } vTable.SetColumn(metaColumn, column); } } if (data.type == Data.DataType.Select && vTable.dataSelectSet.IsManyToMany()) { DebugUtility.LogError("Cannot build the view table '" + vTable.GetName() + "' using a many-to-many select statement. Specify a row value for your select statement where condition(s)."); MemoryProfilerAnalytics.AddMetaDatatoEvent <MemoryProfilerAnalytics.LoadViewXMLEvent>(7); } return(vTable); } }
// a column declaration only creates or adds to the column meta data. it does not create the actual column. public void BuildOrUpdateDeclaration(ViewTable.Builder.BuildingData buildingData, ViewTable vTable, ref MetaColumn metaColumn, Operation.ExpressionParsingContext expressionParsingContext, Type aOverrideType = null) { Type finalType = aOverrideType != null ? aOverrideType : (value == null ? null : value.type ); //Build meta data var mergeAlgo = BuildOrGetMergeAlgo(null, finalType, metaColumn); BuildOrUpdateMetaColumn(buildingData, ref metaColumn, finalType, mergeAlgo); if (metaColumn != null && metaColumn.Type.scriptingType == null && finalType == null && !buildingData.FallbackColumnType.ContainsKey(metaColumn)) { Operation.Expression.ParseIdentifierOption parseOpt = new Operation.Expression.ParseIdentifierOption(buildingData.Schema, vTable, true, false, null, expressionParsingContext); var fallbackType = Operation.Expression.ResolveTypeOf(value, parseOpt); if (fallbackType != null) { buildingData.FallbackColumnType.Add(metaColumn, fallbackType); } } }
public ViewColumnNode(ViewTable viewTable, MetaColumn metaColumn, Operation.ExpressionParsingContext parsingContext) { this.viewTable = viewTable; this.metaColumn = metaColumn; ParsingContext = parsingContext; }
public void Build(Node node, ViewTable vTable, ViewTable parent, ViewSchema vs, Database.Schema baseSchema, Operation.ExpressionParsingContext parentExpressionParsingContext, MetaTable metaTable) { // build selects vTable.dataSelectSet = dataSelectSet.Build(vTable, vs, baseSchema); if (vTable.dataSelectSet != null) { // add the select set to the expression parsing context hierarchy. see [Figure.1] vTable.expressionParsingContext = new Operation.ExpressionParsingContext(vTable.expressionParsingContext, vTable.dataSelectSet); } // build columns switch (type) { case Data.DataType.Node: // these column are declarations foreach (var colb in column) { MetaColumn metaColumn = metaTable.GetColumnByName(colb.name); bool hadMetaColumn = metaColumn != null; colb.BuildOrUpdateDeclaration(ref metaColumn); // add the metacolum to the metatable if it just got created if (!hadMetaColumn) { metaTable.AddColumn(metaColumn); } } // for node type we need to build all child node right away as they defines the entries in this viewtable var validChildNodeIndices = new List <int>(); int iValidChild = 0; for (int iChild = 0; iChild != child.Count; ++iChild) { var c = child[iChild]; if (c.EvaluateCondition(vs, vTable, vTable.expressionParsingContext)) { validChildNodeIndices.Add(iChild); c.BuildAsNode(vTable, (long)iValidChild, vs, baseSchema, vTable.expressionParsingContext); ++iValidChild; } } if (iValidChild != child.Count) { vTable.ValidChildNodeIndices = validChildNodeIndices.ToArray(); } else { vTable.ValidChildNodeIndices = null; } break; case DataType.Select: // these columns are instances of ViewColumn. They have the result of select statement as entries foreach (var colb in column) { MetaColumn metaColumn = metaTable.GetColumnByName(colb.name); bool hadMetaColumn = metaColumn != null; var newColumn = colb.Build(node, vs, baseSchema, vTable, vTable.expressionParsingContext, ref metaColumn); // add the metacolum to the metatable if it just got created if (!hadMetaColumn) { metaTable.AddColumn(metaColumn); } vTable.SetColumn(metaColumn, newColumn.GetColumn()); } break; } }