使用ezAPI将派生列添加到数据流时,我收到以下警告
“在此处添加内容。输入[派生列输入] .Columns [ad_zip]”on“添加 这里的东西“使用类型为READONLY,但未被引用 表达。从可用输入列表中删除列 列,或在表达式中引用它。
我试图删除输入列,但是方法不起作用或者我做错了:
foreach (Microsoft.SqlServer.Dts.Pipeline.Wrapper.IDTSInputColumn100 col in derFull.Meta.InputCollection[0].InputColumnCollection)
{
Console.WriteLine(col.Name);
derFull.DeleteInputColumn(col.Name);
}
答案 0 :(得分:1)
我有以下代码来解决问题。
我是从一个名叫Daniel Otykier的家伙那里得到的。所以他可能是应该归功于它的人......除非他从其他人那里得到它: - )
static public void RemoveUnusedInputColumns(this EzDerivedColumn component)
{
var usedLineageIds = new HashSet<int>();
// Parse all expressions used in new output columns, to determine which input lineage ID's are being used:
foreach (IDTSOutputColumn100 column in component.GetOutputColumns())
{
AddLineageIdsFromExpression(column.CustomPropertyCollection, usedLineageIds);
}
// Parse all expressions in replaced input columns, to determine which input lineage ID's are being used:
foreach (IDTSInputColumn100 column in component.GetInputColumns())
{
AddLineageIdsFromExpression(column.CustomPropertyCollection, usedLineageIds);
}
var inputColumns = component.GetInputColumns();
// Remove all input columns not used in any expressions:
for (var i = inputColumns.Count - 1; i >= 0; i--)
{
if (!usedLineageIds.Contains(inputColumns[i].LineageID))
{
inputColumns.RemoveObjectByIndex(i);
}
}
}
static private void AddLineageIdsFromExpression(IDTSCustomPropertyCollection100 columnProperties, ICollection<int> lineageIds)
{
int lineageId = 1;
var expressionProperty = columnProperties.Cast<IDTSCustomProperty100>().FirstOrDefault(p => p.Name == "Expression");
if (expressionProperty != null)
{
// Input columns used in expressions are always referenced as "#xxx" where xxx is the integer lineage ID.
var expression = expressionProperty.Value.ToString();
var expressionTokens = expression.Split(new[] { ' ', ',', '(', ')' });
foreach (var c in expressionTokens.Where(t => t.Length > 1 && t.StartsWith("#") && int.TryParse(t.Substring(1), out lineageId)))
{
if (!lineageIds.Contains(lineageId)) lineageIds.Add(lineageId);
}
}
}
答案 1 :(得分:0)
在EzApi扩展的基础组件上调用ReinitializeMetaData:
dc.Comp.ReinitializeMetaData();
这并不总是尊重EzAPI所拥有的一些自定义和逻辑检查,因此请仔细测试。但是,对于大多数香草组件,这应该可以正常工作。
您可以使用EzApi的SetUsageType包装器方法将这些VirtualInputColumns的UsageType属性设置为枚举值DTSUsageType.UT_IGNORED。
但是!您必须在之后完成修改组件的任何其他元数据(附加其他组件,添加新的输入或输出列等),因为每个元素都会触发{组件上的{1}}方法,自动将所有UT_IGNORED ReinitializeMetaData
VirtualInputColumn
设置(或重置)为UsageType
。
所以一些示例代码:
UT_READONLY
答案 2 :(得分:0)
我确实遇到了你的问题并找到了解决问题的方法。问题是EzDerivedColumn没有在其类中定义PassThrough。
您只需要将其添加到课程中:
private PassThroughIndexer m_passThrough;
public PassThroughIndexer PassThrough
{
get
{
if (m_passThrough == null)
m_passThrough = new PassThroughIndexer(this);
return m_passThrough;
}
}
并将ReinitializeMetadataNoCast()
改为:
public override void ReinitializeMetaDataNoCast()
{
try
{
if (Meta.InputCollection[0].InputColumnCollection.Count == 0)
{
base.ReinitializeMetaDataNoCast();
LinkAllInputsToOutputs();
return;
}
Dictionary<string, bool> cols = new Dictionary<string, bool>();
foreach (IDTSInputColumn100 c in Meta.InputCollection[0].InputColumnCollection)
cols.Add(c.Name, PassThrough[c.Name]);
base.ReinitializeMetaDataNoCast();
foreach (IDTSInputColumn100 c in Meta.InputCollection[0].InputColumnCollection)
{
if (cols.ContainsKey(c.Name))
SetUsageType(0, c.Name, cols[c.Name] ? DTSUsageType.UT_READONLY : DTSUsageType.UT_IGNORED, false);
else
SetUsageType(0, c.Name, DTSUsageType.UT_IGNORED, false);
}
}
catch { }
}
这是其他组件使用的策略。如果您想查看所有代码,可以查看我的EzApi2016@GitHub。我将原始代码从Microsoft更新到SQL Server 2016。