【问题标题】:Web Service Call with CLR Table Valued Function使用 CLR 表值函数调用 Web 服务
【发布时间】:2016-06-22 23:04:24
【问题描述】:

我正在尝试将几个 TVR 放在一起,但我一直收到以下错误:

从用户定义的表值函数获取新行时出错:

System.InvalidCastException:无法将“System.Char”类型的对象转换为“ResultRow”类型。

CLR.WorkFunctions.FillRow 处的 System.InvalidCastException(对象 resultsObj, SqlString&policyURL、SqlString&fileCachePath、SqlString&identity、 SqlString&格式,SqlString&用户名,SqlString&密码,SqlString&数据)

我正在尝试调用一个对传递的数据执行一些工作的 Web 服务,然后将返回的值加载到枚举器中。但是,如上所示,我反复遇到输入错误,此时我不确定原因。我的想法是它变得不安,因为我试图用字符串而不是 SqlStrings 填充行,所以我改变了它。但是,Web 服务只接受字符串形式的参数,所以我必须在 Web 服务调用中将它们转换过来。这是我的代码:

public class WorkFunctions
    {
        private class ResultRow
        {
            public string PolicyURL;
            public string FileCachePath;
            public string Identity;
            public string Format;
            public string UserName;
            public string Password;
            public string Data;
        }
    [Microsoft.SqlServer.Server.SqlFunction(
               FillRowMethodName = "FillRow",
               TableDefinition = "policyName nvarchar(500), fileCache nvarchar(500), 
               identity nvarchar(500), format nvarchar(500), userName nvarchar(500), 
               password nvarchar(500), data nvarchar(500)")]
            public static IEnumerable Work(SqlString serviceURL, SqlString policyURL, SqlString fileCachePath, SqlString identity, SqlString format, SqlString userName, SqlString password, SqlString data)
           {
              IEnumerable values;

              try
                {
                    CLR.Work.WorkService.WorkMethods workMethods = new CLR.Work.WorkService.WorkMethods();
                    workMethods.Url = Convert.ToString(serviceURL);
                    values = workMethods.Work(Convert.ToString(policyURL), Convert.ToString(identity), Convert.ToString(format), Convert.ToString(userName), Convert.ToString(password), Convert.ToString(fileCachePath), Convert.ToString(data));
                }
              catch (Exception ex)
                {
                   return "Failed to return data";
                }

              return values;
          }

            public static void FillRow(Object resultObj, 
              out SqlString policyURL, out SqlString fileCachePath, 
              out SqlString identity, out SqlString format, 
              out SqlString userName, out SqlString password, 
              out SqlString data)
                 {
                   ResultRow resultRow = (ResultRow)resultObj;

                   policyURL = new SqlString(resultRow.PolicyURL);
                   fileCachePath = new SqlString (resultRow.FileCachePath);
                   identity = new SqlString (resultRow.Identity);
                   format = new SqlString (resultRow.Format);
                   userName = new SqlString (resultRow.UserName);
                   password = new SqlString (resultRow.Password);
                   data = new SqlString (resultRow.Data);
            
                }
      }
}

这是我第一次与 TVF 合作,我对目前可能导致此问题的原因感到有些茫然。如果有人能提供一些想法,我将不胜感激。

谢谢。

【问题讨论】:

    标签: c# user-defined-functions sqlclr


    【解决方案1】:

    最直接的问题最可能的原因是workMethods.Work() 方法返回的类型与您定义为ResultRow 的类型不同。无论workMethods.Work() 返回并分配给values,都将作为结果返回,并将其作为Object 类型的第一个参数发送到FillRowMethod。按照这些思路,您可能应该删除 IEnumerable values; 和 return values; 行,然后执行以下操作:

    ResultRow _Row = new ResultRow();
    
    ...
    
    _Row = workMethods.Work(...);
    
    yield return _Row;
    

    此外,无需在任何SqlString 输入参数上使用Convert.ToString()。所有Sql* 类型都有一个.Value 属性,该属性返回预期的.NET 类型。所以只需使用serviceURL.Value、policyURL等即可。

    最后,为什么输出字段与输入参数几乎相同?似乎是一个奇怪的签名。

    附:如果您想要/需要更多关于使用 SQLCLR 的一般信息,我正在 SQL Server Central 上写一个关于这个主题的系列:Stairway to SQLCLR。该网站确实需要免费注册才能查看其内容(但这是值得的,因为各种文章和论坛中有大量信息)。

    【讨论】:

    • 谢谢,这是有道理的。 Web 服务函数返回一个字符串,并且无法更改 Web 服务,因此我也无法将其更改为类型 ResultRow。最好的前进道路是以某种方式使用字符串列表吗?另外,感谢您对知识库的提醒。这听起来非常有用。
    • @user2498668 如果返回一个字符串,是XML的字符串还是JSON的字符串?如果是 XML,则可以在 C# 代码或 T-SQL 中解析,如果是 JSON,则需要在 C# 中解析,除非您计划使用 SQL Server 2016。但目前您的 TVF 正在返回结果集ResultRow 中定义的字段,因此您需要将数据解析为该字段或考虑使用新结构。为什么是字符串列表?除非您的意思是对 Web 服务的返回值进行简单拆分,在这种情况下也可以。如果您发布了网络服务的回报,我可能会更具体。
    猜你喜欢
    • 1970-01-01
    • 2015-12-28
    • 1970-01-01
    • 2016-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多