Ich verwende Dapper, um eine .net-Core-API mit Oracle DB zu verbinden. Ich habe die folgenden Methoden.
public IDbConnection GetConnection()
{
var connectionString = configuration.GetSection("ConnectionStrings").GetSection("AsyncDB").Value;
var conn = new OracleConnection(connectionString);
return conn;
}
public Object GetProducts()
{
//throw new System.NotImplementedException();
object result = null;
try
{
OracleDynamicParameters dynamicParameters = new OracleDynamicParameters();
dynamicParameters.Add("EMPCURSOR", OracleDbType.RefCursor, ParameterDirection.Output);
var conn = this.GetConnection();
if (conn.State == ConnectionState.Closed)
{
conn.Open();
}
if (conn.State == ConnectionState.Open)
{
var query = "SPGETPRODUCTINFO";
result = SqlMapper.Query(conn, query, param: dynamicParameters, commandType: CommandType.StoredProcedure);
}
}
catch (Exception e)
{
throw e;
}
return result;
}
Die Prozedur SPGETPRODUCTINFO gibt Zeilen aus der Datenbank zurück.
Wie kann die Methode mit async / await-Schlüsselwörtern in eine asynchrone Methode umgewandelt werden?
Zunächst muss Ihre Methode in Async konvertiert werden
public Object GetProducts()
zu
public async Task<Object> GetProductsAsync();
public async Task<Object> GetProductsAsync(CancellationToken cancellationToken = default(CancellationToken));
Wenn eine Methode die Async-Implementierung unterstützt, zeigen allgemeine Konventionen, dass der Methodenname mit dem Async-Schlüsselwort endet.
Sie können Methoden überprüfen, ob sie über eine asynchrone Implementierung verfügen. Wenn beispielsweise SqlMapper.Query
über eine Async-Implementierung verfügt, ist dies im Allgemeinen wie SqlMapper.QueryAsync
.
Darüber hinaus hat Async-Implementierungen den Rückgabetyp Task. Um die Async-Implementierung auszuführen, können Sie dies tun
result = await SqlMapper.QueryAsync(conn, query, param: dynamicParameters, commandType: CommandType.StoredProcedure);
Wenn Sie möchten, dass Ihre Methode Annullierung unterstützt, müssen Sie CancellationToken cancellationToken = default(CancellationToken)
als Parameter festlegen
result = await SqlMapper.QueryAsync(conn, query, param: dynamicParameters, commandType: CommandType.StoredProcedure, cancellationToken: cancellationToken);
Sie machen diese Methode asynchron, genauso wie Sie jede andere Methode asynchron machen. Sie markieren die Methode als async und lassen eine Task zurückgeben, wenn sie void oder Task zurückgibt, wobei T die Klasse ist, die zuvor zurückgegeben wurde. Ändern Sie es, um eine synchrone Version aller verfügbaren Methoden zu verwenden, und warten Sie auf die Ergebnisse.
Ihre Ausnahmebehandlung hier ist nicht gut. Zuerst machst du throw e;
wo e eine gefangene Ausnahme ist. Tu das nicht Wenn Sie eine abgefangene Ausnahme erneut throw;
müssen, throw;
einfach throw;
. Auf diese Weise bewahren Sie Ihre Stapelspur auf. Auch dieser Versuch / Fang ist völlig sinnlos. Wenn Sie keine Abhilfemaßnahmen ergreifen oder etwas protokollieren, hat dies keinen Sinn. Sie können Try / Catch vollständig aus diesem Code entfernen.
Sie behandeln Ihre Datenbankverbindung nicht ordnungsgemäß. OracleConnection implementiert IDisposable . Sie müssen entweder eine using-Anweisung verwenden oder sie in einem finally-Block ablegen.
Der Klassenname sagt: GetProducts, aber Sie geben nur ein Objekt zurück. Das ist nicht sehr gut. Jetzt muss jeder konsumierende Code in den richtigen Typ umgewandelt werden, um ihn verwenden zu können. Der Sinn von Dapper besteht darin, dass Ihre Abfrage einem stark typisierten Objekt zugeordnet werden kann. Basierend auf dem Namen dieser Methode sollten Sie ein IEnumerable oder ähnliches zurückgeben.
Sie überprüfen den Status Ihrer Datenbankverbindung, sobald Sie sie erhalten haben. Das hat keinen Sinn. Wenn Sie eine neue Verbindung erhalten, können Sie davon ausgehen, dass die Verbindung geschlossen ist und Sie sie öffnen müssen.
Wenn man all das in Betracht zieht, sollte man so etwas bekommen:
public IDbConnection GetConnection()
{
var connectionString = configuration.GetSection("ConnectionStrings").GetSection("AsyncDB").Value;
var conn = new OracleConnection(connectionString);
return conn;
}
public Task<IEnumerable<Product>> GetProducts()
{
OracleDynamicParameters dynamicParameters = new OracleDynamicParameters();
dynamicParameters.Add("EMPCURSOR", OracleDbType.RefCursor, ParameterDirection.Output);
const string query = "SPGETPRODUCTINFO";
using (var conn = this.GetConnection())
{
await conn.OpenAsync();
var products = await conn.QueryAsync<Product>(query, param: dynamicParameters, commandType: CommandType.StoredProcedure);
return products;
}
}
Nun, da GetProducts async ist, muss jede über ihr aufgerufene Methode async sein und geändert werden, um eine Task zurückzugeben und abzuwarten. Und jede Methode, die aufruft, muss asynchron sein und geändert werden, um eine Task zurückzugeben und darauf zu warten. Den Call Stack ganz nach oben, bis Sie zu einem Event-Handler oder zur Hauptmethode Ihrer Anwendung gelangen.