c# - 如何解决 CallBimlScript 中的 "Unable to cast object of type ' System.String'"

标签 c# biml

我有一个 BIML 解决方案,它使用 BimlScript 通过三层调用多个 .biml 文件。我在 CallBimlScript() 中传递了一个 AstConnectionNode 参数。但是,当我使用 AstConnectionNode 参数调用它时,我收到错误消息“无法将‘System.String’类型的对象转换为类型‘Varigence.Languages.Biml.Connection.AstOleDbConnectionNode’。”

  1. 参数名称是connectionWrk。我将参数初始化为第一层的连接节点:

    <# var connStrWrk = "Data Source=SomeServer;Initial Catalog=SomeDatabase;Provider=SQLNCLI11.1;Integrated Security=SSPI;Auto Translate=False;"; #>
    <# var connectionWrk = SchemaManager.CreateConnectionNode("SchemaProvider", connStrWrk); #>
    
  2. 然后我将它作为参数传递到第一层的 CallBimlScript 方法中:

    <#=CallBimlScript("01.01.02.GenStg_STD_FullLoad.biml", table, columnList, tableNorm, connectionWrk) #>
    
  3. 它映射到第二层“01.01.02.GenStg_STD_FullLoad.biml”中的被调用者参数:

    <#@ import namespace="System.Data" #> 
    
    <#@ property name="table" type="Varigence.Languages.Biml.Table.AstTableNode" #>
    <#@ property name="columnList" type="String" #>
    <#@ property name="tableNorm" type="String" #>
    <#@ property name="connectionWrk" type="Varigence.Languages.Biml.Connection.AstOleDbConnectionNode" #>
    
  4. 然后我再次将它用作第二层的 CallBimlScript() 中的参数:

    <#=CallBimlScript("01.01.01.a.x.SourceFromClause.biml", hashTable, tableNorm, LoadType, connectionWrk) #>
    
  5. 它被映射到第三层的被调用者:

    <#@ import namespace="System.Data" #>
    
    <#@ property name="hashTable" type="Varigence.Languages.Biml.Table.AstTableNode" required="False"#>
    <#@ property name="tableNorm" type="String" required="True"#>
    <#@ property name="LoadType" type="String" required="True"#>
    <#@ property name="connectionWrk" type="Varigence.Languages.Biml.Connection.AstOleDbConnectionNode" required="True" #>`
    
  6. 然后我用它来获取 SQL Server 数据库中的元数据:

    <#
    var JoinLogic = ExternalDataAccess.GetDataTable(connectionWrk.ConnectionString, 
                                             "SELECT [TABLE_NAME_SRC], [FROM_TABLE], [RANK], " +
                                             "[JOIN_TYPE], [JOIN_TABLE], [JOIN_KEY], [WHERE_CLAUSE] " +
                                             "FROM [PHDDV_VMC_WORK].[ETL_WORK].[VMC_STG_FROM_WHERE_CLS] " +
                                             "WHERE [TABLE_NAME_SRC] = '" + tableNorm + "' " + 
                                             "AND [FROM_TABLE] != '" + tableNorm + "' " + 
                                             "ORDER BY [RANK]; "
                                             ).Rows.OfType<DataRow>().Select(r => new[]
                                                                                      {
                                                                                       r["TABLE_NAME_SRC"].ToString(),
                                                                                       r["FROM_TABLE"].ToString(),
                                                                                       r["RANK"].ToString(),
                                                                                       r["JOIN_TYPE"].ToString(),
                                                                                       r["JOIN_TABLE"].ToString(),
                                                                                       r["JOIN_KEY"].ToString(),
                                                                                       r["WHERE_CLAUSE"].ToString()
                                                                                      });
    #>
    

据我所知,它在所有三个层中都具有 Varigence.Languages.Biml.Connection.AstOleDbConnectionNode 类型。

在之前的 BIML 解决方案中,通过多个层使用一个参数对我来说很有效,但这次我对如何让这个参数在所有三个层中都被解释为 AstOleDbConnectionNode 感到困惑。

为什么它会被解释为 String 类型,我该如何解决或排除故障?

我需要能够在模块化代码中使用此连接节点参数,以便在多个 BIML 文件中重用逻辑。

最佳答案

从第三层/第 5 步中删除所需的 true/false(或更改您的调用顺序)。我会去找笔记,但我认为我记得它影响了参数的顺序。从逻辑上讲,这是有道理的 - 您必须先提供所需的参数,然后列出可选参数。

我快速复制了一个,你可以通过使 4 看起来像来验证行为

<#=CallBimlScript(child, columnList, tableNorm, connectionWrk, table) #>

(或者您已经修改了第二层中的值)

我的复制品

一级代码

<Biml xmlns="http://schemas.varigence.com/biml.xsd">
<# var connStrWrk = @"Data Source=.\dev2017;Initial Catalog=tempdb;Provider=SQLNCLI11.1;Integrated Security=SSPI;Auto Translate=False;"; #>
<# var connectionWrk = SchemaManager.CreateConnectionNode("SchemaProvider", connStrWrk); #> 
<# string child = "so_54450877.tier2.biml" ;
   Varigence.Languages.Biml.Table.AstTableNode table = new Varigence.Languages.Biml.Table.AstTableNode(null);
   table.Name = "tablename";
   string columnList = "column,list";
   string tableNorm = "tablenormname";
   #>
<#=CallBimlScript(child, table, columnList, tableNorm, connectionWrk) #>
</Biml>

二级代码

<#@ import namespace="System.Data" #> 

<#@ property name="table" type="Varigence.Languages.Biml.Table.AstTableNode" #>
<#@ property name="columnList" type="String" #>
<#@ property name="tableNorm" type="String" #>
<#@ property name="connectionWrk" type="Varigence.Languages.Biml.Connection.AstOleDbConnectionNode" #>
<!-- Tier 2 debug -->
<# string child = "so_54450877.tier3.biml" ;
var results = ExternalDataAccess.GetDataTable(connectionWrk,"SELECT 'This is tier 2' AS TierName;") ;
foreach (System.Data.DataRow row in results.Rows)
{
    for (int columnIndex = 0; columnIndex < results.Columns.Count; columnIndex++)
    {
        Write(string.Format("<!-- {0} -->\t", row[columnIndex]));
    }

    Write("\n");
}

#>
<#=CallBimlScript(child, columnList, tableNorm, connectionWrk, table) #>
<!-- Tier 2 end debug -->

第 3 层代码

<#@ import namespace="System.Data" #>

<#@ property name="hashTable" type="Varigence.Languages.Biml.Table.AstTableNode" required="False"#>
<#@ property name="tableNorm" type="String" required="True"#>
<#@ property name="LoadType" type="String" required="True"#>
<#@ property name="connectionWrk" type="Varigence.Languages.Biml.Connection.AstOleDbConnectionNode" required="True" #>
<!-- I exist -->
<# 
string connstring = connectionWrk.ConnectionString;
var results = ExternalDataAccess.GetDataTable(connectionWrk,"SELECT 'This is tier 3' AS TierName;") ;

foreach (System.Data.DataRow row in results.Rows)
{
    for (int columnIndex = 0; columnIndex < results.Columns.Count; columnIndex++)
    {
        Write(string.Format("!<-- {0} -->\t", row[columnIndex]));
    }

    Write("\n");
}
#>

结果

Debug output

关于c# - 如何解决 CallBimlScript 中的 "Unable to cast object of type ' System.String'",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54450877/

相关文章:

c# - 如何以编程方式启动 IIS 6.0 SMTP 虚拟服务器?

c# - 收到广播的UDP包后获取客户端IP

C# webbrowser - 触发右键单击

c# - SSIS 脚本组件在手动打开之前无法加载程序集

sql - SSIS BIML 生成带括号的 SQL 代码

c# - 从 BIML 脚本自动生成 SSIS 包

c# - Windows Phone IsolatedStorageSettings 和 Mutex

C# 奇怪的 WPF 组合框行为

mysql - BIML 创建错误的元数据

c# - 用于读取 SSIS 项目参数的 BimlScript C# 代码块