Sicherstellen, dass die Datenbankverbindung jedes Mal geöffnet und geschlossen wird, wenn ich Dapper für den Zugriff auf die Datenbank verwende

c# dapper database-connection sql sql-server

Frage

Hier ist, was ich gerade in einer meiner Repository-Klassen mache:

private IDbConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnString"].ConnectionString);

public IEnumerable<Product> GetProducts(int categoryId = null, bool? active = null)
{
    StringBuilder sql = new StringBuilder();
    sql.AppendLine("SELECT * ");
    sql.AppendLine("FROM Product ");
    sql.AppendLine("WHERE @CategoryId IS NULL OR CategoryId = @CategoryId ");
    sql.AppendLine("  AND @Active IS NULL OR Active = @Active");

    return this.db.Query<Product>(sql.ToString(), new { CategoryId = categoryId, Active = active }).ToList();
}

Eine Sache, die ich tun möchte, ist, die IDbConnection-Eigenschaft in ein BaseRepository zu setzen, von dem alle meine anderen Repos erben. Was kann ich tun, um sicherzustellen, dass meine Datenbankverbindung ordnungsgemäß in jeder meiner Datenzugriffsfunktionen wie im obigen Beispiel geöffnet und geschlossen wird? Hier ist, was ich derzeit mit Entity Framework mache (mit einer Anweisung um jede Funktion herum, aber jetzt wechsle ich die DAL, um reinen Dapper zu verwenden:

using (var context = new MyAppContext())
{
    var objList = (from p in context.Products
                   where (categoryId == null || p.CategoryId == categoryId) &&
                         (active == null || p.Active == active)
                   select p).ToList();

    return objList;
}

Ich habe in den Dapper- Beispielen festgestellt, dass alles in einer using-Anweisung verpackt ist, wie ich es erwarten würde, aber gelegentlich sehe ich, wie sie ihre Funktionen im folgenden wie folgt umschließt:

using (var connection = Program.GetClosedConnection())

GetClosedConnection () gibt eine neue SqlConnection zurück, aber was ist der Unterschied zwischen den beiden?

public static SqlConnection GetOpenConnection(bool mars = false)
{
    var cs = connectionString;
    if (mars)
    {
        SqlConnectionStringBuilder scsb = new SqlConnectionStringBuilder(cs);
        scsb.MultipleActiveResultSets = true;
        cs = scsb.ConnectionString;
    }
    var connection = new SqlConnection(cs);
    connection.Open();
    return connection;
}
public static SqlConnection GetClosedConnection()
{
    return new SqlConnection(connectionString);
}

Akzeptierte Antwort

So habe ich das immer gemacht:

SqlConnection dbConnection;
using (dbConnection = new SqlConnection(connectionString))
{
    /* 
       Whatever Dapper stuff you want to do. Dapper will open the
       connection and the using will tear it down.
    */
}

Was den zweiten Teil Ihrer Frage GetClosedConnection , instantiiert GetClosedConnection einfach ein SqlConnection Objekt, während GetOpenConnection ein SqlConnection Objekt instanziiert und öffnet . Sie (oder Dapper) müssen Open() für das von GetClosedConnection Objekt manuell aufrufen.


Beliebte Antwort

Diese Antwort basiert auf Ihrem Wunsch, Wiederholungen zu vermeiden.

Machen Sie eine Erweiterungsklasse von Dapper und fügen Sie Funktionen hinzu und verwenden Sie diese stattdessen. Wie so:

    public IEnumerable<T> Query<T>(string sqlQuery, object parameters = null)
    {
        this.activeConnection.Open();

        var result = this.activeConnection
            .Query<T>(sqlQuery, parameters);

        this.activeConnection.Close();

        return result;
    }

Und in der Spitze der Klasse legte ein

    public SqlConnection activeConnection { get; private set; }

Was immer im Konstruktor der Klasse festgelegt ist.



Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum