0

When I run this code:

return dbAccess.ExecuteDataTable(dbAccess)
               .AsEnumerable()
               .Select(r => r.Field<int>("Id"))
               .ToList();                       

It gives me an error:

SqlParameter is already in the SqlParameterCollection

Although I know that AsEnumerable works on this concept deferred execution or lazy loading, but this concept still hasnt made a place in my head.

Can anyone please explain the working of AsEnumerable and this code?

Grant Winney
  • 65,241
  • 13
  • 115
  • 165
Lakshay Dulani
  • 1,710
  • 2
  • 18
  • 45

2 Answers2

0

The equivalent of your code is the following

var retVal = new List<int>();
var dataTable = dbAccess.ExecuteDataTable(dbAccess);
foreach(DataRow r in dataTable.Rows)
{
    var rowResult = (int)r["Id"]; //`(int)r["Id"]` is equivalent to `r.Field<int>("Id")`
    retVal.Add(rowResult);
}
return retVal;

You don't need to worry about differed execution with your code because you put a .ToList() at the end so it runs the code right at the spot you showed us. If you left that out it would have been much harder to show a "equivalent code" without using yield return which could have confused you more.

The above being said, the only thing in the above code that could throw your error that I see is dbAccess.ExecuteDataTable(dbAccess);. Try rewriting your code as the above and see which line your error happens on and perhaps it will give you the direction on where to look next.

Scott Chamberlain
  • 124,994
  • 33
  • 282
  • 431
0

The AsEnumerable just cast the object to IEnumerable (from IQeuriable), which means any LINQ operator you would use, would use the operator declared for that interface (IEnumerable).

This means that instead of translating you operators to SQL, and let the server handle it, the whole table would enumerated (retrieved from the DB), and then manipulated in memory.

As @Scott Chamberlain mentioned, what I answered is irrelevant to your code, as it using DataTable, and not IQueriable. The AsEnumerable just creates enumerable wrapper to the DataTable which retrieve each row at a time, and allows you to use LINQ on the DataTable. This has nothing to do with the exception.

Another thing, Calling ToList force the execution of the query, so execution isn't deferred.

To answer you question about the exception, it would be helpful if you would provide the code where you add parameters to the query.

Shlomi Borovitz
  • 1,700
  • 9
  • 9
  • He does not have a `IQueryable` he has a `DataTable`, the `AsEnumerable()` he is calling is [this version](http://msdn.microsoft.com/en-us/library/system.data.datatableextensions.asenumerable%28v=vs.110%29.aspx) not [this version](http://msdn.microsoft.com/en-us/library/bb335435%28v=vs.110%29.aspx) – Scott Chamberlain Mar 08 '14 at 15:59