【问题标题】:Retrieving Data Type of Measures from an MDX Query/CellSet in C#从 C# 中的 MDX 查询/单元集中检索度量的数据类型
【发布时间】:2012-03-30 22:48:55
【问题描述】:

(我使用的是 C# 4.0。我通过 Microsoft.AnalysisServices.AdomdClient 命名空间/库连接到数据立方体。)

如果我理解正确,MDX SELECT 语句中恰好有一个轴将包含度量;其他的将基于其他维度。

我的直接任务(我相信较大的任务无关紧要)给定一个 MDX SELECT 语句,这样第一个轴包含所述度量,我需要以编程方式确定与每个度量相关的所有单元格。

我认为,一种方法是使用 AdomdConnection 并引用 CubeDef 类来获取度量信息,并将其与 Cellset.Set.Tuples.Members 之类的东西相匹配,但是如何解释在 SELECT 中使用“WITH”关键字进行即时测量?

另一种方法是通过执行 SELECT 语句查看与给定度量关联的 Cell 对象的 Value 属性,并在 CellSet 中找到一个非空 Cell,但我们不能保证找到一个非空值,所以这不是万无一失的。

我在 VS 调试器中查看了 CellSet,但没有找到任何提供此信息的属性。

解决办法: 事实证明,一个度量可能有多种数据类型。至少对于使用WITH 子句定义的度量,如下所示:

WITH MEMBER [Measures].[Dud] AS CASE WHEN [Measures].[Original] > 500 THEN 'A' ELSE 0 END

因此,数据类型信息存储在每个单元格中,而不是存储在某种度量元数据中。随后,学习模式的唯一方法是假设它们都是相同的类型,然后遍历度量维度,直到找到一个非空单元格,然后学习其类型。

【问题讨论】:

    标签: mdx


    【解决方案1】:

    我们实际上基于 ADOMD 数据提供程序编写了自己的 .NET Framework 数据提供程序。我们希望在今年晚些时候将其开源,但以下是我如何完成您想要完成的任务的一些摘录。

    我使用了 AdomdCommand 对象的 ExecuteXmlReader。返回的 xml 将包含单元格的一部分。

    AdomdCommand command = new AdomdCommand();
    command.Connection = new AdomdConnection(connectionString);
    command.Connection.Open();
    command.CommandText = query;
    var doc = XDcoument.Load(command.ExecuteXmlReader());
    
    var cellData = from cell in doc.Root.Elements(_namespace + "CellData").Elements(_namespace + "Cell")
                           select new
                           {
                               Ordinal = (int)cell.Attribute("CellOrdinal"),
                               FormattedValue = cell.Elements(_namespace + "FmtValue").Any() ? cell.Element(_namespace + "FmtValue").Value : cell.Element(_namespace + "Value").Value,
                               Value = cell.Element(_namespace + "Value").Value,
                               Type = (string)cell.Element(_namespace + "Value").Attribute(_xsiNs + "type"),
    
                           };
    

    每个单元格都有一个数据类型。对于给定的列,我们需要该列中的所有单元格。

    var x = cells.Where(c => ((c.Ordinal + 1) % columnCount) == columnPosition).Select(t => t.Type).Distinct();
     if (x.Count() > 1)
            {
                // if a non number comes back, the type is null, so non numbers are null
                // on counts of greater than 1 and no nulls, we have multiple number types, make them all double to accommodate the differences
                if ( !x.Contains(null) )
                {
                    // mix of numbers not doubles, default to int
                    if (!x.Contains("xsd:double"))
                    {
                        type = typeof(int);
                    }
                    else
                    {
                        type = typeof(double);
                    }
                }
                else
                {
                    type = typeof(string);
                }
            }
            else
            {
                // entire column maybe null, default to string, otherwise check
                if (x.Count() == 1)
                {
                    type = ConvertXmlTypeToType(x.First());
                }               
            }
    

    终于有了将 Xml 类型转换为 .NET 类型的函数

    private Type ConvertXmlTypeToType(string type)
        {
            Type t = typeof(string);
    
            switch (type)
            {
                case "xsd:int":
                    t = typeof(int);
                    break;
                case "xsd:double":
                    t = typeof(double);
                    break;
                case "xsd:long":
                    t = typeof(long);
                    break;
                case "xsd:short":
                    t = typeof(short);
                    break;
                case "xsd:integer":
                    t = typeof(int);
                    break;
                case "xsd:decimal":
                    t = typeof(decimal);
                    break;
                case "xsd:float":
                    t = typeof(float);
                    break;
                default:
                    t = typeof(string);
                    break;
            }
    
            return t;
        }               
    

    【讨论】:

    • 感谢您的回复! // entire column maybe null, default to string, otherwise check 这是否意味着如果一整列是null(假设2轴),我们不确定类型,你只是猜测它是一个字符串?
    • 正确,因为没有任何结果,我假设最坏的情况是字符串。最好假设反对,但我还没有看到任何表明这是必要的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-04
    相关资源
    最近更新 更多