0

I am trying to delete multiple rows in EF5 and I'm using the following code sample

string TestId = "12,23";
Context.Database.ExecuteSqlCommand("DELETE FROM TEST WHERE TESTID IN (@Params)", new SqlParameter("Params", TestId));

How do I pass SqlParameter for IN ? I am trying to pass a string of comma-separated values

Thanks

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Peru
  • 2,871
  • 5
  • 37
  • 66

1 Answers1

0

The only way you can pass dynamic number of values in the SQL query TESTID IN (...) part is to use a subselect. That applies to SQL query itself, so there is no parameter type that will solve your issue.

Your alternative is to build the query dynamically by using string concatenation and careful verification of each argument.

Since you are working with IDs they are probably integers.

List<int> testId = ...;
var sb = new StringBuilder();
sb.Append("DELETE FROM TEST WHERE TESTID IN (");
bool first = true;
foreach (var i in testId)
{
    if (first)
        first = false;
    else
        sb.Append(",");
    sb.Append(i.ToString(CultureInfo.InvariantCulture));
}
sb.Append(")");
Context.Database.ExecuteSqlCommand(sb.ToString());

Since there are no string arguments that are being appended to the query you are safe from any SQL injections - there is no way an integer will contain malicious SQL code.

The usual approach when the number of IDs is very large (so that the query will fail during compilation for being too long) is to create a temp table and insert the IDs in it.

Another alternative is to pass in the values formatted as XML and in the SQL query write a subselect that retrieves them from the XML string.

Knaģis
  • 20,827
  • 7
  • 66
  • 80
  • 1
    So it is better i can delete using linq to Entities rather this way ? to avoid foreach i used this. Any suggestions ? – Peru May 22 '13 at 13:32
  • I usually only do this when there is a large number of entities to be deleted. The classic EF approach requires a SELECT that is followed by DELETE. You might first see if `Context.Tests.Local.FirstOrDefault(o => o.id == x)` returns `null` (`.Local` contains only the objects already in memory) - if not, delete using EF, otherwise delete directly in SQL. – Knaģis May 22 '13 at 13:35