2016-03-08 18 views
0

我试图拼凑几个TVR的,我坚持了以下错误:Web服务调用使用CLR表值函数

An error occurred while getting new row from user defined Table Valued Function :

System.InvalidCastException: Unable to cast object of type 'System.Char' to type 'ResultRow'.

System.InvalidCastException at CLR.WorkFunctions.FillRow(Object resultsObj, SqlString& policyURL, SqlString& fileCachePath, SqlString& identity, SqlString& format, SqlString& userName, SqlString& password, SqlString& data)

我试图调用做一些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的工作,我在一个小的损失的是关于什么可能在这一点上会造成这个问题。如果有人能提供一些想法,我会很感激。

谢谢。

回答

0

最直接的问题最可能的原因是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等。

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

P.S.如果您希望/需要关于SQLCLR的更多信息,我正在编写一系列有关SQL Server Central的此主题:Stairway to SQLCLR。该网站确实需要免费注册才能查看其内容(但值得一试,因为各种文章和论坛中都有大量的信息)。

+0

谢谢,这是有道理的。 Web服务函数返回一个字符串,并且更改Web服务不是一个选项,所以我无法将其更改为键入ResultRow。最好的路径是以某种方式使用字符串列表吗? 另外,感谢有关知识库的负责人。这听起来非常有用。 – user2498668

+0

@ user2498668如果它返回一个字符串,它是XML还是JSON字符串?如果是XML,可以在C#代码或T-SQL中解析,如果使用JSON,则需要在C#中解析,除非您计划使用SQL Server 2016.但是,目前您的TVF正在返回结果集字段在'ResultRow'中定义,因此您需要将数据解析为该数据或者考虑新的结构。为什么要列出字符串?除非你的意思是简单地从Web服务中分​​离出返回值,在这种情况下也是可以的。如果您发布了来自Web服务的回报,我可能会更具体。 –