ssis - 如何根据生成的代码编译 BIMLScript

标签 ssis biml

我正在使用 BIML 创建一个带有 ScriptComponentProject 的 ScriptComponenteSource。 该项目包含以下内容(取自 Varigence 样本)

<ScriptProjects>
    <ScriptComponentProject Name="SC_AD-Accounts" TargetFrameworkVersion="NetFX461">
        <AssemblyReferences>
            <AssemblyReference AssemblyPath="System" />
            <AssemblyReference AssemblyPath="System.Data" />
            <AssemblyReference AssemblyPath="System.Windows.Forms" />
            <AssemblyReference AssemblyPath="System.Xml" />
            <AssemblyReference AssemblyPath="Microsoft.SqlServer.TxScript" />
            <AssemblyReference AssemblyPath="Microsoft.SqlServer.DTSRuntimeWrap" />
            <AssemblyReference AssemblyPath="Microsoft.SqlServer.DTSPipelineWrap" />
            <AssemblyReference AssemblyPath="Microsoft.SqlServer.PipelineHost" />
            <AssemblyReference AssemblyPath="System.DirectoryServices" />
        </AssemblyReferences>

        <OutputBuffers>
            <OutputBuffer Name="Output0">
                <Columns>
                    <Column Name="UUId" DataType="String" Length="255" />
                    <Column Name="Surname" DataType="String" Length="255" />
                    <Column Name="GivenName" DataType="String" Length="255" />
                    <Column Name="EmailAddress" DataType="String" Length="255" />
                    <Column Name="UPN" DataType="String" Length="255" />
                </Columns>
            </OutputBuffer>
        </OutputBuffers>

        <Files>
            <File Path="main.cs"><![CDATA[
using System;
using System.Data;
using System.DirectoryServices;
using Microsoft.SqlServer.Dts.Pipeline;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;

[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public partial class ScriptMain : UserComponent
{
    public override void CreateNewOutputRows()
    {
        /*
          Add rows by calling the AddRow method on the member variable named "<Output Name>Buffer".
          For example, call MyOutputBuffer.AddRow() if your output was named "MyOutput".
        */

        var searchBaseNames = new [] {
            "OU=UserP,OU=User,DC=MyDC",
            "OU=UserPS,OU=User,DC=MyDC",
            "OU=UserPSC,OU=User,DC=MyDC"
        };

        var propertiesToLoad = new [] {
            "sn",
            "givenName",
            "mail",
            "userPrincipalName",
            "objectGuid",
            "serialNumber"
        };

        foreach (var searchBaseName in searchBaseNames) {
            var searchBaseEntry = new DirectoryEntry("LDAP://" + searchBaseName);

            var directorySearcher = new DirectorySearcher(searchBaseEntry, "(objectClass=user)", propertiesToLoad, SearchScope.Subtree) {
                PageSize = 2500
            };

            foreach (SearchResult searchResult in directorySearcher.FindAll()) {
                var surname = searchResult.Properties["sn"][0] as string;
                var givenName = searchResult.Properties["givenName"][0] as string;
                var email = searchResult.Properties["mail"][0] as string;
                var upn = searchResult.Properties["userPrincipalName"][0] as string;

                string uuid = null;

                if(searchResult.Properties.Contains("serialNumber"))
                {
                    uuid = searchResult.Properties["serialNumber"][0] as string;
                    if(!string.IsNullOrEmpty(uuid))
                        uuid = uuid;
                }

                if(string.IsNullOrEmpty(uuid))
                {
                    var objectGuidBytes = searchResult.Properties["objectGuid"][0] as byte[];
                    var objectGuid = new Guid(objectGuidBytes);

                    uuid = objectGuid.ToString();
                }

                if(string.IsNullOrEmpty(surname) || string.IsNullOrEmpty(givenName) || 
                   string.IsNullOrEmpty(upn) || string.IsNullOrEmpty(email))
                {
                    continue;
                }

                Output0Buffer.AddRow();
                Output0Buffer.Surname = surname;
                Output0Buffer.GivenName = givenName;
                Output0Buffer.UPN = upn;
                Output0Buffer.EmailAddress = email;
            }
        }
    }
}
            ]]></File>
        </Files>
    </ScriptComponentProject>
</ScriptProjects>

这不会编译,因为 BIML 扩展不知道 Output0Buffer 和重写方法(它们将自动创建)。

有没有办法解决这个母鸡先有蛋的问题?

最佳答案

我在博客上谈到了这一点, https://billfellows.blogspot.com/2015/10/biml-script-component-source.html

您需要将输出缓冲区的 IsSynchronous 属性指定为 false。否则,它将将该组件视为同步转换。

<OutputBuffer Name="Output0" IsSynchronous="false">

祝我评论我的代码

        <OutputBuffers>
            <!--    
            Define what your buffer is called and what it looks like
            Must set IsSynchronous as false. Otherwise it is a transformation
            (one row enters, one row leaves) and not a source.
            -->
            <OutputBuffer Name="DemoOutput" IsSynchronous="false">
                <Columns>
                    <Column Name="SourceColumn" DataType="String" Length="50" /> 
                </Columns>                    
            </OutputBuffer>                                 
        </OutputBuffers>

关于ssis - 如何根据生成的代码编译 BIMLScript,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61500795/

相关文章:

c# - SSIS C# 脚本任务不读取变量或参数

ssis - 如何以编程方式在 SSIS 中使用 "Foreach From Variable Enumerator"创建 foreach 循环

visual-studio-2019 - 安装插件后找不到 Biml

sql-server - 为什么 NULL 值在事实表中映射为 0?

sql-server - SSIS 自定义组件 salesforce 源 (kingswaysoft) 未通过 BIML 正确配置

tsql - BIML GetDropAndCreateDdl 为数据类型创建不正确的长度

sql-server-2005 - SSIS 脚本组件写入变量

sql-server - 尝试通过 DTExec.exe 运行 SSIS 包时出现 Appcrash Kernelbase.dll 错误

sql - SSIS Union All 不返回所有记录