如何对 CallBimlScript 中的 "Unable to cast object of type 'System.String'" 进行故障排除
How to troubleshoot "Unable to cast object of type 'System.String'" in CallBimlScript
我有一个 BIML 解决方案,它使用 BimlScript 通过三层调用多个 .biml 文件。我在 CallBimlScript() 中传递了一个 AstConnectionNode 参数。但是,当我使用 AstConnectionNode 参数调用它时,我收到错误消息 "Unable to cast object of type 'System.String' to type 'Varigence.Languages.Biml.Connection.AstOleDbConnectionNode'."
参数名称为connectionWrk。我将参数初始化为第一层的连接节点:
<# var connStrWrk = "Data Source=SomeServer;Initial Catalog=SomeDatabase;Provider=SQLNCLI11.1;Integrated Security=SSPI;Auto Translate=False;"; #>
<# var connectionWrk = SchemaManager.CreateConnectionNode("SchemaProvider", connStrWrk); #>
然后我将它作为参数传递到第一层的 CallBimlScript 方法中:
<#=CallBimlScript("01.01.02.GenStg_STD_FullLoad.biml", table, columnList, tableNorm, connectionWrk) #>
它映射到第二层“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" #>
然后我再次将它用作第二层的 CallBimlScript() 中的参数:
<#=CallBimlScript("01.01.01.a.x.SourceFromClause.biml", hashTable, tableNorm, LoadType, connectionWrk) #>
并且映射到第三层的被调用方:
<#@ 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" #>`
然后我用它来获取 SQL 服务器数据库中的元数据:
<#
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 文件中重用逻辑。
从第三个 tier/step 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 -->
Tier 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");
}
#>
结果
我有一个 BIML 解决方案,它使用 BimlScript 通过三层调用多个 .biml 文件。我在 CallBimlScript() 中传递了一个 AstConnectionNode 参数。但是,当我使用 AstConnectionNode 参数调用它时,我收到错误消息 "Unable to cast object of type 'System.String' to type 'Varigence.Languages.Biml.Connection.AstOleDbConnectionNode'."
参数名称为connectionWrk。我将参数初始化为第一层的连接节点:
<# var connStrWrk = "Data Source=SomeServer;Initial Catalog=SomeDatabase;Provider=SQLNCLI11.1;Integrated Security=SSPI;Auto Translate=False;"; #> <# var connectionWrk = SchemaManager.CreateConnectionNode("SchemaProvider", connStrWrk); #>
然后我将它作为参数传递到第一层的 CallBimlScript 方法中:
<#=CallBimlScript("01.01.02.GenStg_STD_FullLoad.biml", table, columnList, tableNorm, connectionWrk) #>
它映射到第二层“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" #>
然后我再次将它用作第二层的 CallBimlScript() 中的参数:
<#=CallBimlScript("01.01.01.a.x.SourceFromClause.biml", hashTable, tableNorm, LoadType, connectionWrk) #>
并且映射到第三层的被调用方:
<#@ 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" #>`
然后我用它来获取 SQL 服务器数据库中的元数据:
<# 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 文件中重用逻辑。
从第三个 tier/step 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 -->
Tier 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");
}
#>
结果