12

I am trying to execute below code. My goal is to check whether any user exists with the given email id or not.

var result = userDbContext.users.SqlQuery("SELECT * FROM USERS WHERE @email='@emailValue'",
new SqlParameter("@email", "email"),
new SqlParameter("@emailValue","abc@mail.com"));
//new SqlParameter("p1", existingUser.password));

if (result.Count() == 0) //getting exception here
{
    ViewBag.comment = "Sorry. We can not find your credentials";
    return View();
}

But I am getting exception at result.count() and don't know what is going wrong.

Exception is:

"The SqlParameter is already contained by another SqlParameterCollection"

How can I solve this?

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
Amit
  • 451
  • 2
  • 6
  • 19

5 Answers5

6

You just need to add ToList() method after the Sql query and remove @ in SqlParameter:

var result = userDbContext.users.SqlQuery("SELECT * FROM USERS WHERE 
@email=@emailValue",
new SqlParameter("email", "email"),
new SqlParameter("emailValue","abc@mail.com")).ToList();
//new SqlParameter("p1", existingUser.password));

if (result.Count() == 0) //getting exception here
{
    ViewBag.comment = "Sorry. We can not find your credentials";
    return View();
}

It will work.

  • 1
    This is the most likely answer to others with the same problem. I was calling SqlQuery with a stored proc and just one parameter. Kept getting the same error and spent ages trying to resolve it. Added ToList to the end of my statement and voila - problem fixed. – PoorbandTony Jan 08 '20 at 09:31
3

When you are using params by query, you can't use them by another query. In your code you are using them twice

1- userDbContext.users.SqlQuery....
2- result.Count().

but if you use this code:

"userDbContext.users.SqlQuery(...).Count()" 

your Code will be Correct

** SqlQuery does not return a query result until you use a linq extension like any(), tolist()..... on the other hand when you use SqlQuery, the result is an IEnumerable when you use any(), tolist(), first() it's converted to a result

Theresa
  • 3,515
  • 10
  • 42
  • 47
amin
  • 561
  • 6
  • 18
  • 1
    @Theresa: Thank u theresa. but can u tell me why my answer received negative point.? – amin Oct 26 '15 at 07:45
2

do something like this:

SqlParameter parameter = new SqlParameter("email", SqlDbType.VarChar);
parameter.Value = "test@yahoo.com";

or try like this:

var check =userDbContext.Database
           .SqlQuery<user>("SELECT * FROM USERS 
                           WHERE email=@emailValue", 
                           new SqlParameter("@emailValue","abc@mail.com")).ToList();

SqlParameter is like this:

var p = new SqlParameter {
    ParameterName = "paramName",
    DbType = DbType.Bit,
    Direction = ParameterDirection.Output
};
Ehsan Sajjad
  • 61,834
  • 16
  • 105
  • 160
0

Sticking .ToList() on the end and just in this place makes the query execute. Any subsequent calls to the original query before the ToList will throw this error, but if you use the ToList result then it will work fine.

I had the same problem as I used an Any() which ran the query and then after I ran First() against the query without the ToList. It tries to run the query again but it has already run and hence has those parameters already defined. So in summary slap ToList on the end and use that result object as you dont want to execute the SQL query again.

Andrew
  • 2,571
  • 2
  • 31
  • 56
-3

You can try this

var check = (from item in userDbContext.users where item.email == email select item).FirstOrDefault();
if (check == null)
{
    ViewBag.comment = "Sorry. We can not find your credentials";
    return View();
}
Nadeem Shaikh
  • 362
  • 5
  • 23