user1416726
user1416726

Reputation: 1

Parsing Columns Expressions in C#

I’m trying to parse a column expression for a DataTable in ADO.NET and identify the set of dependent column names that are contained within it.

Example:

A DataTable has 3 columns Unit Price, Quantity and BreakEven.

We could derive two additional columns via column expressions.

[Total Sale Value] = “IIF([Unit Price] > 0, [Unit Price] * Quantity, 0)”
[Profit or Loss Indication] = “IIF([Total Sale Value]> BreakEven, ‘Profit’, ‘Loss’)”

When I manually parse the column expression for [Total Sale Value], I want to be able to pick up [Unit Price] and “Quantity” as the set of source columns that are contained within it.

Also, when I parse the column expression for [Profit or Loss Indication], I want to be able to pick up [Total Sale Value] and “BreakEven” as the set of source columns that are contained within it.

From what I can see, even though the .net framework has its own mechanism for parsing column expressions, it does not expose any of that functionality via public classes and methods.

Upvotes: 0

Views: 958

Answers (2)

Daniel Smith
Daniel Smith

Reputation: 329

If you want to be super hacky, you could do something like this:

public static class DataColumnExtensions
{
    private static readonly Assembly DataAssembly = Assembly.GetAssembly(typeof(DataTable));

    public static bool DependsOn(this DataColumn thisColumn, DataColumn otherColumn)
    {
        if (string.IsNullOrEmpty(thisColumn.Expression))
        {
            return false;
        }

        var dataExpression = DataAssembly.CreateInstance(
            "System.Data.DataExpression",
            false,
            BindingFlags.Default | BindingFlags.CreateInstance | BindingFlags.Instance | BindingFlags.NonPublic,
            null,
            new object[] { thisColumn.Table, thisColumn.Expression, thisColumn.DataType },
            null,
            null);

        var dependsOnMethod = dataExpression.GetType().GetMethod("DependsOn", BindingFlags.NonPublic | BindingFlags.Instance);

        var result = (bool)dependsOnMethod.Invoke(dataExpression, new object[] { otherColumn });

        return result;
    }
}

Upvotes: 1

to StackOverflow
to StackOverflow

Reputation: 124726

It's complex - I'd have thought the only way you can do this reliably is by copying the .NET Framework code, i.e. the internal System.Data.DataExpression class, then related classes such as ExpressionNode.

Upvotes: 0

Related Questions