ExecuteNonQuery: Connection property has not been initialized - enterprise-library

I've seen this question asked here before, but never when Enterprise Library is used. I've used code like the following before and it works fine. What's the problem this time? I get the error on the last line:
Database db = new SqlDatabase(MyConfiguration.Current.ConnectionString);
DbCommand cmd = db.GetStoredProcCommand("AddWorkListItem");
db.AddInParameter(cmd, "#PartNumber", DbType.String, partNumber);
db.AddInParameter(cmd, "#Quantity", DbType.Int32, qty);
db.AddInParameter(cmd, "#WorkListTypeCode", DbType.String, code);
db.AddInParameter(cmd, "#UserKey", DbType.Int32, userKey);
return cmd.ExecuteNonQuery();

Gosh it's been a while but I'm pretty sure you call db.ExecuteNonQuery(cmd) rather than cmd.ExecuteNonQuery(). Have you tried that?

Related

Cannot drop Firebird table when using multiple connections

I would like to safely drop Firebird table. I have 3 transactions, one to recreate table, one to do something with the table (just inserting a single row to keep it simple) and the last one to drop the table.
If all these txns are executed using single connection these works. If I use a different connection, then the drop command fails with
lock conflict on no wait transaction
unsuccessful metadata update
object TABLE "DEMO" is in use
private static void Test() {
using var conn1 = new FbConnection(ConnectionString);
using var conn2 = new FbConnection(ConnectionString);
using var conn3 = new FbConnection(ConnectionString);
conn1.Open();
conn2.Open();
conn3.Open();
ExecuteTxn(conn1, cmd => {
cmd.CommandText = "recreate table demo (id int primary key)";
cmd.ExecuteNonQuery();
});
ExecuteTxn(conn2, cmd => {
cmd.CommandText = "insert into demo (id) values (1)";
cmd.ExecuteNonQuery();
});
ExecuteTxn(conn3, cmd => {
cmd.CommandText = "drop table demo";
cmd.ExecuteNonQuery();
});
}
private static void ExecuteTxn(FbConnection conn, Action<FbCommand> todo) {
using (var txn = conn.BeginTransaction())
using (var cmd = conn.CreateCommand()) {
cmd.Transaction = txn;
todo(cmd);
txn.Commit();
}
}
I realized that changing the transaction options as
txn = conn.BeginTransaction(new FbTransactionOptions { TransactionBehavior = FbTransactionBehavior.Wait }))
seems to help. But I'm not sure if this the right thing to do or just a coincidence...
Using Firebird 3.0.6, FirebirdSql.Data.FirebirdClient.dll 7.5.0.0
As far as I understand it, the problem has to do with how Firebird caches certain metadata, which might result in existence locks being retained, which will prevent deletion of the object. In addition, it is possible - this is a guess! - that the Firebird ADO.net provider retains the statement handle with the insert statement prepared, which will also result in an existence lock being retained.
Executing in a WAIT transaction (optionally with a timeout) is considered an appropriate workaround by the Firebird core developers.
For reference, see the following tickets:
CORE-3766 - Transaction can`t change metadata if it is run in no_wait and there is another connect that once had queried these metadata
CORE-6382 - Triggers accessing a table prevent concurrent DDL command from dropping that table
In certain cases, switching from Firebird ClassicServer or Firebird SuperClassic to Firebird SuperServer can also prevent this problem.
However, if you want a more in-depth explanation, it might be worthwhile to ask this question on the firebird-devel mailing list.

EntityFrameworkCore, trying to execute raw sql query but get error: "The connection was not closed. The connection's current state is open."

I need to run a raw sql query, but I'm getting an error when I try to open the connection to the database. "The connection was not closed. The connection's current state is open."
_loginValidator and _contactService are passed into the controller through DI:
services.AddScoped<ILoginValidator, LoginValidator>();
services.AddScoped<IContactService, ContactService>();
The two lines below are in an action function of the controller. If I switch the two lines, the error goes away...:
var validationErrors = _loginValidator.Validate(id, "");
var user = _contactService.GetContact(id);
Here is _loginValidator.Validate. If I comment out the second line, the error goes away...:
public LoginValidationResult Validate(int userId, string encryptedPassword)
{
var vr = new LoginValidationResult();
var user = _context.Users.Include(u => u.LoginUserQuestionAnswers).FirstOrDefault(u => u.Id == userId);
//...
}
Here is _contactService.GetContact. This is where I get the error:
public ContactDto GetContact(int id)
{
var conn = _context.Database.GetDbConnection();
//ERROR HERE!!!
conn.Open();
//work on conn, for example: ExecuteReader
conn.Close();
}
Notes:
If I comment out the _context line in the Validate(...) function, I do not get the error.
If I switch the two lines I listed in the action function, I do not get the error.
I think the problem is that EntityCore is not closing the connection after I finish using it in _loginValidator.Validate(...)
Anyone know how I can deal with this problem?
DB Connection is an unmanaged resource and you need to close it yourself. The best practice is to use a using statement for your DB connections.
See these links:
http://stackoverflow.com/questions/35077000/entity-framework-7-get-database-time
https://msdn.microsoft.com/en-us/data/dn456849.aspx
The connection being left open after the FirstOrDefault query is a bug. I filed https://github.com/aspnet/EntityFramework/issues/6581 for it and we just triaged it for the 1.0.2 release.
To workaround the bug for now I think you can check if the connection is already open and, if so, don't try to open it again.

ExecuteReader requires an open connection

I am getting the error: "ExecuteReader requires an open connection" and I know the fix is to add a connection.Open() / connection.Close(). My question pertaining to this error is more for me to understand exactly what happen under the hood.
I am currently using the "USING" statement which I expect it to open and close/dispose the connection for me. So I guess I don't understand why it didn't work as expected and I needed to explicitly code the connection.Open() / connection.Close() myself to fix the issue. I did some research and found people experienced similar issue because they were using static connection. In my case, I am creating a new instance of the connection... hence, it bothers me and hoping to get to the bottom of this instead of just fix it and move on. Thank you in advance.
Here is the code:
try
{
using (SqlConnection connection = new SqlConnection(myConnStr))
using (SqlCommand command = new SqlCommand("mySPname", connection))
{
command.CommandType = CommandType.StoredProcedure;
//add some parameters
SqlParameter retParam = command.Parameters.Add("#RetVal", SqlDbType.VarChar);
retParam.Direction = ParameterDirection.ReturnValue;
/////////////////////////////////////////////////
// fix - add this line of code: connection.Open();
/////////////////////////////////////////////////
using(SqlDataReader dr = command.ExecuteReader())
{
int success = (int)retParam.Value;
// manually close the connection here if manually open it. Code: connection.Close();
return Convert.ToBoolean(success);
}
}
}
catch (Exception ex)
{
throw;
}
Using does not open any connections, it only disposes of any allocated memory after calling End Using.
For the SqlConnection, you have to explicitly open it inside the using block, you just don't need to close it though.
I also notice that you are missing a set of brackets {} around the using SqlConnection. Maybe that's the issue? It should be like this:
try
{
using (SqlConnection connection = new SqlConnection(myConnStr))
{
connection.Open();
using (SqlCommand command = new SqlCommand("InsertProcessedPnLFile", connection))
{
command.CommandType = CommandType.StoredProcedure;
//add some parameters
SqlParameter retParam = command.Parameters.Add("#RetVal", SqlDbType.VarChar);
retParam.Direction = ParameterDirection.ReturnValue;
/////////////////////////////////////////////////
// fix - add this line of code: connection.Open();
/////////////////////////////////////////////////
using(SqlDataReader dr = command.ExecuteReader())
{
int success = (int)retParam.Value;
// manually close the connection here if manually open it. Code: connection.Close();
return Convert.ToBoolean(success);
}
}
}
}

ADO.NET and Disposing without Using

I have a project that isn't using USING anywhere with their ADO.NET code. I am cleaning up their unclosed connections. Is the below code a best practice with try/catch/finally. I also have some that contains SqlTransaction that I'm disposing in between the command and connection dispose.
SqlConnection con = new SqlConnection(ConfigurationManager.AppSettings["MyNGConnectDashBoardConnectionString"].ToString());
SqlCommand cmd = new SqlCommand();
DataSet ds = new DataSet();
try
{
con.Open();
cmd.Connection = con;
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(ds);
}
catch (Exception ex)
{
throw ex;
}
finally
{
cmd.Dispose();
con.Dispose();
}
Actually, there is no need to worry about closing the connection when using the SqlDataAdapter.Fill(dataset) method. This method closes the connection after performing every Fill.
Also, there is no need to call SqlCommand.Dispose() since the command itself has no unmanaged resources to clean up. What you should be concerned about is if SqlConnection.Close() is called at some point. This is done after Fill.
What you have is fine. It is always a good idea to dispose of objects that use unmanaged resources. However, if you get sick of always explicitly calling Dispose, the best practice is probably to use the using:
using (SqlConnection con = new SqlConnection(ConfigurationManager.AppSettings["MyNGConnectDashBoardConnectionString"].ToString()))
{
using (SqlCommand cmd = new SqlCommand())
{
DataSet ds = new DataSet();
try
{
con.Open();
cmd.Connection = con;
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(ds);
}
catch (Exception ex)
{
throw; // I changed this too!
}
}
}
Also, you almost always want to simply throw if you're going to "rethrow" an exception. You lose some of your stack trace if you throw ex;.
The best practice is using using instead of try/finally :)
However in your case even using is not needed, because Fill() closes the connection:
SqlConnection con = new SqlConnection(ConfigurationManager.AppSettings["MyNGConnectDashBoardConnectionString"].ToString())
SqlDataAdapter da = new SqlDataAdapter("your sql is here", con);
da.Fill(ds);
Also simple re-throwing exceptions makes no sense at all. If you need to log error, just use plain throw; as #Cory suggested.

Invalid attempt to call FieldCount when reader is closed

The error above occurs when I try to do a dataReader.Read on the data recieved from the database. I know there are two rows in there so it isnt because no data actually exists.
Could it be the CommandBehavior.CloseConnection, causing the problem? I was told you had to do this right after a ExecuteReader? Is this correct?
try
{
_connection.Open();
using (_connection)
{
SqlCommand command = new SqlCommand("SELECT * FROM Structure", _connection);
SqlDataReader dataReader = command.ExecuteReader(CommandBehavior.CloseConnection);
if (dataReader == null) return null;
var newData = new List<Structure>();
while (dataReader.Read())
{
var entity = new Structure
{
Id = (int)dataReader["StructureID"],
Path = (string)dataReader["Path"],
PathLevel = (string)dataReader["PathLevel"],
Description = (string)dataReader["Description"]
};
newData.Add(entity);
}
dataReader.Close();
return newData;
}
}
catch (SqlException ex)
{
AddError(new ErrorModel("An SqlException error has occured whilst trying to return descendants", ErrorHelper.ErrorTypes.Critical, ex));
return null;
}
catch (Exception ex)
{
AddError(new ErrorModel("An error has occured whilst trying to return descendants", ErrorHelper.ErrorTypes.Critical, ex));
return null;
}
finally
{
_connection.Close();
}
}
Thanks in advance for any help.
Clare
When you use the Using in C#, after the last } from the using, the Connection automatically close, thats why you get the fieldcount to be closed when u try to read him, as that is impossible, because u want those datas, read then before close the using, or u can open and close manually the connection, by not using the (using)
Your code, as displayed is fine. I've taken it into a test project, and it works. It's not immediately clear why you get this message with the code shown above. Here are some debugging tips/suggestions. I hope they're valuable for you.
Create a breakpoint on the while (dataReader.Read()). Before it enters its codeblock, enter this in your Immediate or Watch Window: dataReader.HasRows. That should evaluate to true.
While stopped on that Read(), open your Locals window to inspect all the properties of dataReader. Ensure that the FieldCount is what you expect from your SELECT statement.
When stepping into this Read() iteration, does a student object get created at all? What's the value of dataReader["StructureID"] and all others in the Immediate Window?
It's not the CommandBehavior.CloseConnection causing the problem. That simply tells the connection to also close itself when you close the datareader.
When I got that error, it happened to be a command timeout problem (I was reading some large binary data). As a first attempt, I increased the command timeout (not the connection timeout!) and the problem was solved.
Note: while attempting to find out the problem, I tried to listen to the (Sql)connection's StateChanged event, but it turned out that the connection never fall in a "broken" state.
Same problem here. Tested all the above solutions
increase command timeout
close the connection after read
Here's the code
1 objCmd.Connection.Open()
2 objCmd.CommandTimeout = 3000
3 Dim objReader As OleDbDataReader = objCmd.ExecuteReader()
4 repeater.DataSource = objReader
5 CType(repeater, Control).DataBind()
6 objReader.Close()
7 objCmd.Connection.Dispose()
Moreover, at line 4 objReader has Closed = False
I got this exception while using the VS.NET debugger and trying to examine some IQueryable results. Bad decision because the IQueryable resulted in a large table scan. Stopping and restarting the debugger and NOT trying to preview this particular IQueryable was the workaround.