User Defined Table Types are a very nifty way to pass data to a stored procedure for processing.

Say we have this type:

        FullNames NVARCHAR(100) NOT NULL,
        Age       TINYINT       NOT NULL

And then we have this procedure that accepts this type as a parameter:

CREATE PROC ProcessPeople
    (@People Person READONLY)
    -- this is some dummy processing

We can invoke this from code, using the excellent Dapper library to interact with the database and the DataTableProxy library to allow us to easily map plain C# objects to a DataTable that can then be used to create a structured object for the parameter.

Our program would look like this:

// Create a collection of people
var people = new Person[] { new Person() { Name = "James Bond", Age = 40 },
new Person() { Name = "Evelyn Salt", Age = 30 },
new Person() { Name = "Jason Bourne Salt", Age = 35 }};

// Convert the collection into a datatable

var tableParameter = people.ToTable(new ClassMapping<Person>()
    .AddColumn("Name", i => i.Name)
    .AddColumn("Age", i => i.Age)

// Call the procedure
using (var cn = new SqlConnection("Data source=;database=Empty;trusted_Connection=true"))
    	new { people = tableParameter.AsTableValuedParameter("Person") },
    	commandType: CommandType.StoredProcedure);

This will run fine.

However, if you changed the order of the mapping, like so:

var tableParameter = people.ToTable(new ClassMapping<Person>()
    .AddColumn("Age", i => i.Age)
    .AddColumn("Name", i => i.Name)

Running the program would yield the following:

In other words, for user defined table types, the column order matters - you must pass the columns in the order they were defined

Happy hacking!