USQL在用户定义的类型

时间:2018-04-06 13:43:56

标签: u-sql

UDT

[SqlUserDefinedType(typeof(StudentHistoryFormatter))]
    public struct StudentHistory
    {
        public StudentHistory(int i, double? score, string status):this()
        {
            InstitutionId = i;
            Score = score;
            Status = status;
        }

        int InstitutionId { get; set; }

        double? Score {get; set; }

        string Status { get; set; }

        public string Value()
        {
            return string.Format("{0},{1},{2}", InstitutionId, Score, Status);
        }
    }

为简单起见,我甚至没有把类放在命名空间中。 我使用USQL数据库注册了程序集

USQL

@history =
    EXTRACT InstitutionId int,
            Score double,
            Status string
    FROM @"CoreData\Institution\history.csv"
    USING Extractors.Csv();

@historyMap =
   SELECT InstitutionId,
               ARRAY_AGG<StudentHistory>(new StudentHistory(InstitutionId, Score, Status)) AS History
        FROM @history
        GROUP BY InstitutionId;

错误

  

严重级代码描述项目文件行抑制状态   错误E_CSC_USER_INVALIDCOLUMNTYPE:&#39; Microsoft.Analytics.Types.Sql.SqlArray&#39;不能用作列类型。   描述:   列类型必须是受​​支持的标量,复杂或用户定义的类型。   解析度:   确保列类型是受支持的类型。对于用户定义的类型,请确保已注册类型,类型名称是完全限定的,并且脚本引用了所需的程序集。

1 个答案:

答案 0 :(得分:1)

错误消息有点不清楚。目前,SqlArray中唯一受支持的项类型是内置标量和复杂(SqlArray,SqlMap)类型。目前不支持用户定义的类型。

您可以通过创建自己的ArrayofUDT用户定义类型或将UDT序列化为byte []来建模。

以下是使用ARRAY_AGG的后者示例,假设您有一个ToBinary()方法,允许您将UDT转换为byte []:

@data = SELECT key, ARRAY_AGG( myUDT.ToBinary() ) AS obj_array FROM @input GROUP BY key;

(有关对象序列化选项的信息,请参阅How to convert an object to a byte array in C#

然后,当您想要获取对象时,您将在对象数组上使用CROSS APPLY EXPLODE并使用byte []来重新水化UDT实例。伪代码:

@objects = 
  SELECT myUDT.FromBinary(data) 
  FROM @data CROSS APPLY EXPLODE (obj_array) AS t(data);

请在http://aka.ms/adlfeedback处为复杂类型的UDT提交功能请求。我将针对错误消息提交错误。