How to pass a List of custom objects in a SSIS Script Task?

主宰稳场 提交于 2019-12-12 09:55:50

问题


I have a Script Task that creates a list of custom objects and sets them to an SSIS object variable.

Custom class:

public class Dog
{
    public string Name { get; set; }
}

Code to populate the List and set to an SSIS object variable "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;
}

In a second Script Task, I am trying to read my "myDogs" object variable back into a List:

Custom class copied over in the second Script Task:

public class Dog
{
    public string Name { get; set; }
}

Main code in my second Script Task:

public void Main()
{
    var varDogs = Dts.Variables["myDogs"].Value;
    List<Dog> dogs = new List<Dog>();

    dogs = (List<Dog>)varDogs;
}

My varDogs object correctly loads the data from my SSIS object variable "myDogs". However, when I try to cast varDogs to a List of type Dog I receive an error message saying "Unable to cast object of type System.Collections.Generic.List".

Does anyone know how I would be able to cast this var data back into a List? Thanks.


回答1:


Before you try anything else, compile your custom classes to a .dll and install it to your GAC (Global Assembly Cache). SSIS is really picky when it comes to interacting with custom objects and it expects to find references to them there. The MSDN example of GAC installation can be found here. Once you install the .dll just reference it in your script task and SSIS will search for the GAC signature automatically.

This is the proper way of managing custom objects in SSIS because you are referencing one class in both script tasks. Although the class is identical between your two current script tasks, your error is indicating that they are from separate namespaces.

As others have suggested, serialization would work, but it is a hackish solution at the very least because you would have to maintain the class on both sides (Script Task 1 & Script Task 2). Better to familiarize yourself with the native SSIS solution before you start working with complex types :)




回答2:


Saw your tweet and was curious, but when I first jumped over here I had it in my head that you were doing something closer to the actual SQL Server when I already collected a couple links for you to look at. Also, this isn't likely much of an "answer", although maybe it will help conceptually especially if @billinkc's thought about the serialization issue is part of the issue. Disclaimer, it has been a long time since I've worked in C++ (and yes know you mentioned C#) and I honestly have only stumbled through SSIS a couple times. Lately I've been spending a lot of time "just making it work" in JavaScript/TypeScript worlds, hence the potentially hacky suggestion to follow.

When I only glanced and immediately went to grab a couple links, my thought was what if you were to encode it as JSON especially with the new SQL Server built in functionality. Then grabbed a couple about using JSON in SSIS, but finally a one about encoding/decoding JSON directly in C#. If you are actually running into any serialization/clone/deep copy/type inference issues, I'm guessing this might actually help.

If you aren't familiar with JavaScript, one of the fairly hacky ways to take a "deep copy" of a data object is to convert it to JSON then back out. Keep in mind, JSON is just string data, so there should be no baked in object references/complex types. The question would just be if you can properly cast the output of the JSON decoding "on the other side".

Hopefully you get your dogs all sorted out there...

  • JSON encoding/decoding info for SQL Server - https://docs.microsoft.com/en-us/sql/relational-databases/json/convert-json-data-to-rows-and-columns-with-openjson-sql-server
  • using JSON like a table in SQL Server - https://docs.microsoft.com/en-us/sql/t-sql/functions/openjson-transact-sql
  • loading JSON data in SSIS - https://chris.koester.io/index.php/2017/06/06/download-json-data-with-ssis/
  • parsing JSON as an SSIS data source - https://mycontraption.com/parsing-json-data-sources-using-ssis/
  • parsing JSON in C# - How can I parse JSON with C#?



回答3:


The easiest way when you work with SSIS is to use a DataTable. In this example i have just populated my object through a SQL task to simplify it.

C# Code

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;
}

Datatable result

List outcome




回答4:


Try to add [Serializable()] attribute to your object.



来源:https://stackoverflow.com/questions/32099013/how-to-pass-a-list-of-custom-objects-in-a-ssis-script-task

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!