Bert Wagner
Bert Wagner

Reputation: 881

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

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.

Upvotes: 3

Views: 5027

Answers (4)

SqlKindaGuy
SqlKindaGuy

Reputation: 3591

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

enter image description here

List outcome

enter image description here

Upvotes: 4

Brandon Church
Brandon Church

Reputation: 177

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 :)

Upvotes: 2

Hasan Savran
Hasan Savran

Reputation: 393

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

Upvotes: 0

Brian Jorden
Brian Jorden

Reputation: 1226

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...

Upvotes: 1

Related Questions