Error : There is already an open DataReader associated with this Command which must be closed first
An SqlDataReader should be closed after its use, otherwise it keeps the connection locked and you cannot use that connection until you close it.
However you don't need an SqlDataReader to discover if you have already registered an email address
public bool good(string emailadress)
{
string query = @"IF EXISTS(SELECT 1 FROM Clients WHERE Email = @email)
SELECT 1 ELSE SELECT 0";
SqlCommand cmd = new SqlCommand(query, con);
cmd.Parameters.Add("@email", SqlDbType.NVarChar).Value = emailadress;
int result = (int)cmd.ExecuteScalar();
return (result == 1);
}
Keep in mind that disposable objects like the SqlCommand, the SqlDataReader but of uttermost importance, the SqlConnection should be created at the moment you need them and disposed immediately to free valuable resouces.
The code above with a connection created on the spot would be:
public bool good(string emailadress)
{
string query = @"IF EXISTS(SELECT 1 FROM Clients WHERE Email = @email)
SELECT 1 ELSE SELECT 0";
using(SqlConnection con = new SqlConnection(....here put your connection string...))
using(SqlCommand cmd = new SqlCommand(query, con))
{
con.Open();
cmd.Parameters.Add("@email", SqlDbType.NVarChar).Value = emailadress;
int result = (int)cmd.ExecuteScalar();
return (result == 1);
}
}
Error There is already an open DataReader associated with this Command which must be closed first when using 2 distinct commands
I suggest creating an additional connection for the second command, would solve it. Try to combine both queries in one query. Create a subquery for the count.
while (dr3.Read())
{
dados_historico[4] = dr3["QT"].ToString(); //quantidade de emails lidos naquela verificação
}
Why override the same value again and again?
if (dr3.Read())
{
dados_historico[4] = dr3["QT"].ToString(); //quantidade de emails lidos naquela verificação
}
Would be enough.
There is already an open DataReader associated with this Command which must be closed first error on Entity Framework linq query
Found this answer: Entity Framework: There is already an open DataReader associated with this Command
Which says that it's probably triggered due to nested queries or lazy loading. It sounds like the only way to fix this is to not use lazy loading or to enable MARS (Multiple Active Result Sets).
In your case, it's probably not an actual second connection, but another result set coming from the same connection. I also wonder if it could be due to the ToListAsync()
.
Actually, now that I look at it again, it could be something with the gr.OrderByDescending()
call in the middle of the query? That might be attempting to enumerate the result set in the middle of the outer result set. Maybe try to rewrite the query (even incorrectly) to avoid something like that, and see if the problem goes away.
How to solve there is already an open data reader with this command error?
As coded, the entire operation can be collapsed to just executing an SQL of:
UPDATE shoporder
SET LaborCost = LaborCost + TireRepairCost, TireRepairCost = 0
WHERE TireRepairCost > 0
Minimally that would look like:
private void button1_Click(object sender, EventArgs e)
{
using var c = new SqlCommand("UPDATE shoporder SET LaborCost = LaborCost + TireRepairCost, TireRepairCost = 0 WHERE TireRepairCost > 0", ConnectionString);
c.Connection.Open();
c.ExecuteNonQuery();
}
Footnote
If you're going to be doing a lot of database work like this, switching to using Dapper will help you out. Dapper code would be:
private async void button1_Click(object sender, EventArgs e)
{
using var c = new SqlConnection(ConnectionString);
await c.ExecuteAsync("UPDATE shoporder SET LaborCost = LaborCost + TireRepairCost, TireRepairCost = 0 WHERE TireRepairCost > 0");
}
..but the real magic of Dapper is where you want to run DB queries and get objects:
using var c = new SqlConnection(ConnectionString);
var orders = await c.QueryAsync<ShopOrder>("SELECT * FROM shopOrders WHERE TireRepairCost > @cost", new{ cost = 0 }).ToList();
Just those two lines would give you a list of ShopOrder collection objects to do stuff with. Doing it "the long way" would be more like:
using var c = new SqlCommand("SELECT * FROM shopOrders WHERE TireRepairCost > @cost", ConnectionString);
c.Parameters.AddWithValue("@cost", 0); //btw, google 'addwithvalue is evil'
c.Connection.Open();
var r = c.ExecuteReader();
var orders = new List<ShopOrder>();
while(r.Read()){
orders.Add(new ShopOrder {
Id = r.GetInteger("Id"),
LaborCost = r.GetInteger("LaborCost"),
TireCost = r.GetInteger("TireCost"),
});
}
Painful..
Entity Framework runtime error - There is already an open DataReader associated with this Command which must be closed first
To answer your question, you have your TestContext
wrapped in a using
statement which means that the TestContext
will remain open until the end of the using
statement.
Your initial call is essentially a query which only gets executed when your foreach
loop is hit:
var students = context.Students.Where(s => s.Id == 1);
This is causing the error. I.e., it is resulting in multiple queries on a DataReader
that does not allow it.
@Arman is correct: .ToList()
will solve your problem because the query is being executed to get all the students to a list before the foreach
loop. Obviously, there are a number of solutions to this problem. Probably the most common one would be set MARS (Multiple Active Result Sets) to true on your connection string; i.e.:
Server={myServer};Initial Context={myDb};MultipleActiveResultSets=True;…
This will allow multiple open DataReaders
.
Related Topics
Send JSON via Post in C# and Receive the JSON Returned
C# - How to Iterate Through Classes Fields and Set Properties
How to Set Web.Config File to Show Full Error Message
Looking for a Command Line Argument Parser for .Net
How to Implement Custom Authentication in ASP.NET MVC 5
Limit the Number of Parallel Threads in C#
How to Create an Expression Tree Calling Ienumerable<Tsource>.Any(...)
.Net (Dotnet) Wrappers for Opencv
When to Use Properties Instead of Functions
How to Load All Assemblies from Within Your /Bin Directory
How to Concatenate Two Ienumerable<T> into a New Ienumerable<T>
Best Practices for Serializing Objects to a Custom String Format for Use in an Output File
Accelerating Bitmap Grayscale Conversion, Is Openmp an Option in C#
Binding Datagrid to Observablecollection<Dictionary>
How to Clear Cookies Using ASP.NET MVC 3 and C#