Después de de nuestra prolongada recopilación de información solucionamos esta duda que presentan muchos lectores. Te brindamos la respuesta y esperamos serte de mucha ayuda.
Solución:
Mi pregunta aquí es, que estoy usando
GetDbConnection()
yCreateCommand()
en DbContext, entonces, ¿debo eliminar explícitamente el resultado de cualquiera de esos comandos (o encerrarlos en la declaración de uso)?
Estos son diferentes, y la respuesta es sí para lo segundo, no para lo primero.
Todo lo que necesita es seguir un principio simple: el código que asigna el recurso es responsable de limpiarlo.
GetDbConnection
(como lo indica la palabra Get
) no crea DbConnection
objeto, pero devuelve el creado y utilizado por el DbContext
instancia durante su vida. En este caso el DbContext
posee el DbConnection
por lo que no debe deshacerse de ese objeto (si lo hace, podría romper la funcionalidad del propietario).
Desde el otro lado, CreateCommand
lo hace crear nuevo DbCommand
objeto, por lo que ahora su código lo posee y es responsable de desecharlo cuando ya no se necesite.
El mismo principio se aplica a Open
/ Close
. Nuevamente, su código no es propietario del DbConnection
objeto, por lo que debe dejarlo en el mismo estado en que estaba cuando lo recuperó. EF Core lo hace internamente cuando procesa comandos que necesitan una conexión abierta: ábralo al principio, ciérrelo cuando haya terminado. Excepto si se abrió externamente, en cuyo caso no hacen nada. ¿Cuál es exactamente el principio antes mencionado? Si su código no Open
entonces debería hacer Close
no hagas nada más.
Entonces, el código en cuestión debería ser algo como esto (tenga en cuenta que hay un error en la lógica de cierre de su código: la condición para llamar Close
debiera ser !isOpen
el mismo que se usa para Open
llamar):
public string GetId()
using (var cmd = _context.Database.GetDbConnection().CreateCommand())
bool wasOpen = cmd.Connection.State == ConnectionState.Open;
if (!wasOpen) cmd.Connection.Open();
try
cmd.CommandText = "Select TOP 1 ID from ABC;";
var result = (string)cmd.ExecuteScalar();
return result;
finally
if (!wasOpen) cmd.Connection.Close();
Comentarios y puntuaciones
Si sostienes alguna desconfianza o capacidad de afinar nuestro enunciado puedes realizar una crónica y con gusto lo interpretaremos.