1

I am using EF 6 with MVC5/C#

I am trying to run an insert statement, using SqlParameter objects, via ExecuteStoreCommand over EF. I am doing it this way as I have some performance issues with AddObject.

My code is:

string insertCmd = "INSERT INTO TABLE (Value,FkId) VALUES (@Value,@FkId)";

var paramList = new[]{
    new SqlParameter("@Value", SqlDbType.VarChar).Value = value,
    new SqlParameter("@FkId", SqlDbType.Int).Value = fkId
};

db.ExecuteStoreCommand(insertCmd, paramList);

I am getting the error:

Must declare the scalar variable "@Value". Statement(s) could not be prepared.

I have noticed that it always complains about the first column in the Insert statement regardless of type. So if I swapped it around I would get:

Must declare the scalar variable "@FkId". Statement(s) could not be prepared.

Thoughts ?

EDIT:

Just noticed that the record gets inserted and saved to the DB, yet I still get this error. Puzzled...

1 Answer 1

2

If you look really carefully at the type inferred by the compiler for the variable:

var paramList = new[]
{
    new SqlParameter("@Value", SqlDbType.VarChar).Value = "SomeValue",
    new SqlParameter("@FkId", SqlDbType.Int).Value = 123
};

You'll see that paramList is a an Object[2] with the two scalar values Value(string) and 123(int), and the SqlParameters are lost altogether, because the result of an assignment is the assigned value! Object is inferred by the compiler as the lowest common denominator of string and int.

Unfortunately the call to ExecuteStoreCommand won't give you any warning that you aren't passing SqlParameter[], since it accepts the very weak type params object[] as per the docs:

The parameters value can be an array of DbParameter objects or an array of parameter values

To solve this, you can either use one of the SqlParameter constructors which take on the value directly, e.g.

var paramList = new[]
{
    new SqlParameter("@Value", "SomeValue"),
    new SqlParameter("@FkId", 123)
};

Or create the parameters, assign them, and then add to the array.

Out of interest, ExecuteStoreCommand is a method on ObjectContext, not DbContext.

There's an equivalent method DbContext.Database.ExecuteSqlCommand which should do the same thing.

Sign up to request clarification or add additional context in comments.

1 Comment

Just tried your first suggestion, and it worked. Really love your very comprehensive reply. I see the Object Type now ! So grateful.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.