Share via


Calculated Column Representation (Tabular)

A calculated column is DAX expression that creates a new column in a table and the obtained values are stored in the table; the calculated column expression is evaluated every time the table is processed.

Calculated Column Representation

In tabular object models the calculated column is a column in a table whose values are calculated upon definition of the column, from an expression.

Calculated Columns in AMO

When using AMO to manage a Tabular Model table there is no one-to-one object match for a calculated column in AMO; in AMO a calculated column is represented by an attribute in a Dimension and an attribute in MeasureGroup.

The following code snippet shows how to add a calculated column to an existing tabular model. The code assumes you have an AMO database object, newDatabase, and an AMO cube object, modelCube.

        private void addCalculatedColumn(
                           AMO.Database newDatabase
                         , AMO.Cube modelCube
                         , String ccTableName
                         , String ccName
                         , String newCalculatedColumnExpression
                     )
        {
            if (string.IsNullOrEmpty(ccName) || string.IsNullOrWhiteSpace(ccName))
            {
                MessageBox.Show(String.Format("Calculated Column name is not defined."), "AMO to Tabular message", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            if (string.IsNullOrEmpty(newCalculatedColumnExpression) || string.IsNullOrWhiteSpace(newCalculatedColumnExpression))
            {
                MessageBox.Show(String.Format("Calculated Column expression is not defined."), "AMO to Tabular message", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (newDatabase.Dimensions[ccTableName].Attributes.Contains(ccName))
            {
                MessageBox.Show(String.Format("Calculated Column name already defined."), "AMO to Tabular message", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            //Add CC attribute to the Dimension
            AMO.Dimension dim = newDatabase.Dimensions[ccTableName];
            AMO.DimensionAttribute currentAttribute = dim.Attributes.Add(ccName, ccName);
            currentAttribute.Usage = AMO.AttributeUsage.Regular;
            currentAttribute.KeyUniquenessGuarantee = false;

            currentAttribute.KeyColumns.Add(new AMO.DataItem(ccTableName, ccName, OleDbType.Empty));
            currentAttribute.KeyColumns[0].Source = new AMO.ExpressionBinding(newCalculatedColumnExpression);
            currentAttribute.KeyColumns[0].NullProcessing = AMO.NullProcessing.Preserve;
            currentAttribute.NameColumn = new AMO.DataItem(ccTableName, ccName, System.Data.OleDb.OleDbType.WChar);
            currentAttribute.NameColumn.Source = new AMO.ExpressionBinding(newCalculatedColumnExpression);
            currentAttribute.NameColumn.NullProcessing = AMO.NullProcessing.ZeroOrBlank;

            currentAttribute.OrderBy = AMO.OrderBy.Key;
            AMO.AttributeRelationship currentAttributeRelationship = dim.Attributes["RowNumber"].AttributeRelationships.Add(currentAttribute.ID);
            currentAttributeRelationship.Cardinality = AMO.Cardinality.Many;
            currentAttributeRelationship.OverrideBehavior = AMO.OverrideBehavior.None;

            //Add CC as attribute to the MG
            AMO.MeasureGroup mg = modelCube.MeasureGroups[ccTableName];
            AMO.DegenerateMeasureGroupDimension currentMGDim = (AMO.DegenerateMeasureGroupDimension)mg.Dimensions[ccTableName];
            AMO.MeasureGroupAttribute mga = new AMO.MeasureGroupAttribute(ccName);

            mga.KeyColumns.Add(new AMO.DataItem(ccTableName, ccName, OleDbType.Empty));
            mga.KeyColumns[0].Source = new AMO.ExpressionBinding(newCalculatedColumnExpression);


            currentMGDim.Attributes.Add(mga);

            try
            {
                //Update Dimension, CubeDimension and MG in server
                newDatabase.Update(AMO.UpdateOptions.ExpandFull, AMO.UpdateMode.UpdateOrCreate);
            }
            catch (AMO.OperationException amoOpXp)
            {
                MessageBox.Show(String.Format("Calculated Column expression contains syntax errors, or references undefined or missspelled elements.\nError message: {0}", amoOpXp.Message), "AMO to Tabular message", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            catch (AMO.AmoException amoXp)
            {
                MessageBox.Show(String.Format("AMO exception accessing the server.\nError message: {0}", amoXp.Message), "AMO to Tabular message", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            catch (Exception)
            {
                throw;
            }
        }

AMO2Tabular sample

To have an understanding on how to use AMO to create and manipulate calculated column representations see the source code of the AMO to Tabular sample; specifically check in the following source file: AddCalculatedColumn.cs. The sample is available at Codeplex. An important note about the code: the code is provided only as a support to the logical concepts explained here and should not be used in a production environment; nor should it be used for other purpose other than the pedagogical one.