Situation
I have many parameterized SQL commands. I execute these commands one after the other in a loop and looks like this:
public void SaveChanges()
{
using (var ts = _Context.Database.BeginTransaction())
{
try
{
_Context.SaveChanges();
foreach (var cmd in _Commands)
{
if (cmd.Parameter != null)
{
_Context.Database.ExecuteSqlCommand(cmd.Sql, cmd.Parameter.ToArray());
}
}
ts.Commit();
}
catch (Exception ex)
{
ts.Rollback();
throw new Exception("SaveChanges");
}
}
}
The above code works, also transcaction rollback works as expected.
My command class looks like this:
public class SqlBuilderCommand
{
public string Sql { get; set; }
public List<SqlParameter> Parameter {get;set;}
}
Possible duplicates without concrete solution
I have figured out several, possible duplicates to this question. The closest one is this:
Unfortunately, it doesn't help me with the Entity Framework (or I just don't get it)
Questions
Is it possible to execute all the commands in the list in one round trip?
If not, is it possible with ADO.NET?
SOLUTION AND DRAWBACKS / LIMITATIONS
Thanks to @Evgeni for the right answer.Yes, you can concatenate many SQL-Strings and just send the parameter as a list in one round trip. That's great.
But there is a limitation with SQL-Server. SQL-Server only accepts a maximum of 2100 parameters with one command. So if you have an object with 7 database columns, the maximum bulk insert is 300 objects per command. Otherwise you get an exception.
If I do that for 5000 objects, it leads to 17 bulk inserts (5000/300). I stopped the time for 5000 objects and it is still 8-9 seconds, which is way too slow, because I know, that raw SQL will do it much, much faster.
At this point, I think there is no way around raw SQL for me, unless someone could tell me, that there is a way to speed up sql commands.
Maybe I will write a follow up question to this. Damn.