Actually, a cool feature of SQL Server 2008 is table valued parameters.
setup:
create type fooTableType as table (v varchar(50));
go
create proc spFoo(@t fooTableType readonly) as
insert into tbFoo(v) select v from @t
go
then your C# code gens:
declare @t as fooTableType
insert @t(v) values('beyond'),('all'),('recognition')
exec spFoo(@t)
here's some rough C# code to do that:
using (SqlCommand cmd=new SqlCommand()) {
StringBuilder sql = new StringBuilder();
for(int i=0; i<50; i++) {
sql.AppendFormat(",(@v{i})",i);
cmd.Parameters.AddWithValue("@v"+i.ToString(),values[i]);
}
cmd.CommandText = "declare @t as fooTableType; insert @t(v) values" +
sql.ToString().Substr(1) + "; exec spFoo(@t);"
cmd.CommandType = CommandType.Text;
cmd.Connection = myConnection;
cmd.ExecuteNonQuery();
}
I would generally agree that such an optimization is not absolutely necessary. Perhaps it is OCD but I wouldn't be able to leave it as a loop of cmd.ExecuteNonQuery().
Check out CertifiedCrazy's answer for a cleaner version of the C# code.
Also note that this technique is limited to 2100 total parameters - this a limitation of the underlying TDS protocol.