如何在 SSIS 脚本任务中传递自定义对象列表?
How to pass a List of custom objects in a SSIS Script Task?
我有一个创建自定义对象列表并将它们设置为 SSIS 对象变量的脚本任务。
自定义 class:
public class Dog
{
public string Name { get; set; }
}
填充列表并设置为 SSIS 对象变量的代码"myDogs":
public void Main()
{
List<Dog> dogs = new List<Dog>();
Dog dog1 = new Dog();
dog1.Name = "Fido";
Dog dog2 = new Dog();
dog1.Name = "Roofus";
dogs.Add(dog1);
dogs.Add(dog2);
Dts.Variables["myDogs"].Value = dogs;
}
在第二个脚本任务中,我试图将我的 "myDogs" 对象变量读回到列表中:
在第二个脚本任务中复制过来的自定义 class:
public class Dog
{
public string Name { get; set; }
}
我的第二个脚本任务中的主要代码:
public void Main()
{
var varDogs = Dts.Variables["myDogs"].Value;
List<Dog> dogs = new List<Dog>();
dogs = (List<Dog>)varDogs;
}
我的 varDogs 对象正确地从我的 SSIS 对象变量 "myDogs" 加载数据。但是,当我尝试将 varDogs 转换为 Dog 类型的列表时,我收到一条错误消息 "Unable to cast object of type System.Collections.Generic.List"。
有谁知道如何将此 var 数据转换回列表?谢谢
看到你的推文,我很好奇,但当我第一次跳到这里时,当我已经为你收集了几个链接到看着。此外,这不太可能是 "answer",尽管它可能在概念上有所帮助,特别是如果 @billinkc 对序列化问题的思考是问题的一部分。免责声明,自从我使用 C++ 工作以来已经有很长一段时间了(是的,知道你提到了 C#),老实说,我只是偶然发现了几次 SSIS。最近我在 JavaScript/TypeScript 世界中花费了很多时间 "just making it work",因此遵循了可能很老套的建议。
当我只看了一眼就立即去抓取几个链接时,我的想法是如果你将它编码为 JSON 尤其是新的 SQL 服务器内置功能。然后抓取了一些关于在 SSIS 中使用 JSON 的内容,但最后是关于直接在 C# 中使用 encoding/decoding JSON 的内容。如果您实际上 运行 陷入任何 serialization/clone/deep copy/type 推理问题,我猜这可能真的有帮助。
如果您不熟悉 JavaScript,获取数据对象 "deep copy" 的一种相当老套的方法是将其转换为 JSON 然后退出。请记住,JSON 只是字符串数据,因此不应包含对象 references/complex 类型。问题只是您是否可以正确转换 JSON 解码 "on the other side" 的输出。
希望你能把你的狗都整理好...
- JSON encoding/decoding SQL 服务器的信息 - https://docs.microsoft.com/en-us/sql/relational-databases/json/convert-json-data-to-rows-and-columns-with-openjson-sql-server
- 像 SQL 服务器中的 table 一样使用 JSON - https://docs.microsoft.com/en-us/sql/t-sql/functions/openjson-transact-sql
- 正在 SSIS 中加载 JSON 数据 -
https://chris.koester.io/index.php/2017/06/06/download-json-data-with-ssis/
- 正在将 JSON 解析为 SSIS 数据源 - https://mycontraption.com/parsing-json-data-sources-using-ssis/
- 在 C# 中解析 JSON - How can I parse JSON with C#?
尝试向您的对象添加 [Serializable()] 属性。
在您尝试任何其他操作之前,将您的自定义 classes 编译为 .dll 并将其安装到您的 GAC(全局程序集缓存)。在与自定义对象交互时,SSIS 非常挑剔,它希望在那里找到对它们的引用。 GAC 安装的MSDN 示例可以找到here。安装 .dll 后,只需在脚本任务中引用它,SSIS 就会自动搜索 GAC 签名。
这是在 SSIS 中管理自定义对象的正确方法,因为您在两个脚本任务中都引用了 one class。尽管 class 在您当前的两个脚本任务之间是相同的,但您的错误表明它们来自不同的命名空间。
正如其他人所建议的那样,序列化会起作用,但它至少是一个 hackish 解决方案,因为您必须在两侧(脚本任务 1 和脚本任务 2)维护 class。在开始使用复杂类型之前,最好熟悉本机 SSIS 解决方案:)
使用 SSIS 时最简单的方法是使用 DataTable
。在这个例子中,我刚刚通过 SQL 任务填充了我的对象以简化它。
C#代码
public class Dog
{
public string Name { get; set; }
}
public void Main()
{
DataTable dt = new DataTable();
OleDbDataAdapter adapter = new OleDbDataAdapter();
adapter.Fill(dt, Dts.Variables["User::myDogs"].Value);
List<Dog> dogList = new List<Dog>();
for (int i = 0; i < dt.Rows.Count; i++)
{
Dog dogs = new Dog();
dogs.Name = dt.Rows[i]["Name"].ToString();
dogList.Add(dogs);
}
Dts.TaskResult = (int)ScriptResults.Success;
}
数据表结果
列出结果
我有一个创建自定义对象列表并将它们设置为 SSIS 对象变量的脚本任务。
自定义 class:
public class Dog
{
public string Name { get; set; }
}
填充列表并设置为 SSIS 对象变量的代码"myDogs":
public void Main()
{
List<Dog> dogs = new List<Dog>();
Dog dog1 = new Dog();
dog1.Name = "Fido";
Dog dog2 = new Dog();
dog1.Name = "Roofus";
dogs.Add(dog1);
dogs.Add(dog2);
Dts.Variables["myDogs"].Value = dogs;
}
在第二个脚本任务中,我试图将我的 "myDogs" 对象变量读回到列表中:
在第二个脚本任务中复制过来的自定义 class:
public class Dog
{
public string Name { get; set; }
}
我的第二个脚本任务中的主要代码:
public void Main()
{
var varDogs = Dts.Variables["myDogs"].Value;
List<Dog> dogs = new List<Dog>();
dogs = (List<Dog>)varDogs;
}
我的 varDogs 对象正确地从我的 SSIS 对象变量 "myDogs" 加载数据。但是,当我尝试将 varDogs 转换为 Dog 类型的列表时,我收到一条错误消息 "Unable to cast object of type System.Collections.Generic.List"。
有谁知道如何将此 var 数据转换回列表?谢谢
看到你的推文,我很好奇,但当我第一次跳到这里时,当我已经为你收集了几个链接到看着。此外,这不太可能是 "answer",尽管它可能在概念上有所帮助,特别是如果 @billinkc 对序列化问题的思考是问题的一部分。免责声明,自从我使用 C++ 工作以来已经有很长一段时间了(是的,知道你提到了 C#),老实说,我只是偶然发现了几次 SSIS。最近我在 JavaScript/TypeScript 世界中花费了很多时间 "just making it work",因此遵循了可能很老套的建议。
当我只看了一眼就立即去抓取几个链接时,我的想法是如果你将它编码为 JSON 尤其是新的 SQL 服务器内置功能。然后抓取了一些关于在 SSIS 中使用 JSON 的内容,但最后是关于直接在 C# 中使用 encoding/decoding JSON 的内容。如果您实际上 运行 陷入任何 serialization/clone/deep copy/type 推理问题,我猜这可能真的有帮助。
如果您不熟悉 JavaScript,获取数据对象 "deep copy" 的一种相当老套的方法是将其转换为 JSON 然后退出。请记住,JSON 只是字符串数据,因此不应包含对象 references/complex 类型。问题只是您是否可以正确转换 JSON 解码 "on the other side" 的输出。
希望你能把你的狗都整理好...
- JSON encoding/decoding SQL 服务器的信息 - https://docs.microsoft.com/en-us/sql/relational-databases/json/convert-json-data-to-rows-and-columns-with-openjson-sql-server
- 像 SQL 服务器中的 table 一样使用 JSON - https://docs.microsoft.com/en-us/sql/t-sql/functions/openjson-transact-sql
- 正在 SSIS 中加载 JSON 数据 - https://chris.koester.io/index.php/2017/06/06/download-json-data-with-ssis/
- 正在将 JSON 解析为 SSIS 数据源 - https://mycontraption.com/parsing-json-data-sources-using-ssis/
- 在 C# 中解析 JSON - How can I parse JSON with C#?
尝试向您的对象添加 [Serializable()] 属性。
在您尝试任何其他操作之前,将您的自定义 classes 编译为 .dll 并将其安装到您的 GAC(全局程序集缓存)。在与自定义对象交互时,SSIS 非常挑剔,它希望在那里找到对它们的引用。 GAC 安装的MSDN 示例可以找到here。安装 .dll 后,只需在脚本任务中引用它,SSIS 就会自动搜索 GAC 签名。
这是在 SSIS 中管理自定义对象的正确方法,因为您在两个脚本任务中都引用了 one class。尽管 class 在您当前的两个脚本任务之间是相同的,但您的错误表明它们来自不同的命名空间。
正如其他人所建议的那样,序列化会起作用,但它至少是一个 hackish 解决方案,因为您必须在两侧(脚本任务 1 和脚本任务 2)维护 class。在开始使用复杂类型之前,最好熟悉本机 SSIS 解决方案:)
使用 SSIS 时最简单的方法是使用 DataTable
。在这个例子中,我刚刚通过 SQL 任务填充了我的对象以简化它。
C#代码
public class Dog
{
public string Name { get; set; }
}
public void Main()
{
DataTable dt = new DataTable();
OleDbDataAdapter adapter = new OleDbDataAdapter();
adapter.Fill(dt, Dts.Variables["User::myDogs"].Value);
List<Dog> dogList = new List<Dog>();
for (int i = 0; i < dt.Rows.Count; i++)
{
Dog dogs = new Dog();
dogs.Name = dt.Rows[i]["Name"].ToString();
dogList.Add(dogs);
}
Dts.TaskResult = (int)ScriptResults.Success;
}
数据表结果
列出结果