一种使用“使用”语句和oracle事务来避免重复代码的正确方法?

时间:2018-08-17 15:07:32

标签: c# oracle dapper

我有一个用于访问所有数据库查询的类(数据访问层)。我将Dapper用作微型ORM。

进行此类查询的“正常”方式是:

string req = @"select ...";
using (var db = new OracleConnection(this.con_str))
{
    return db.Execute(req, { p1, p2});
}

现在,我在此类中有多个方法,我需要进行多重插入。如果一次插入失败,则无论做完什么,我都需要回滚。

因此,除了使用外,我还需要使用现有的连接和事务

IDbTransaction t;
IDbConnection c;
...
dynamic MyInsersion(int p1, int p2){
    string req = @"select ...";
    return c.Execute(req, new { p1, p2 }, transaction: t);
}

我的问题是,仅当c不为null时,myInsersion才需要使用现有连接。如果c为null,则忽略它并创建一个新的连接,而无需事务。我需要一个简短的代码,因为我有很多这样的方法。 我尝试过这样的事情:

using (var db = connection ?? new OracleConnection(this.con_str))

如果连接不为空,则使用它;如果不为空,则创建一个新连接。 问题在于“ using”语句会自动调用db.Dispose(),后者会调用db.close()

所以我必须创建两个几乎相同的代码块

if(c != null && c.State == ConnectionState.Open)
{
    return c.Execute(req, new { p1, p2 }, transaction: t);
}
else
{
    return c.Execute(req, new { p1, p2 });
}

唯一避免这种代码重复的方法是使用lambda:

Action<IDbConnection, IDbTransaction> A = (db, tr) =>
{
    db.Execute(
        req,
        new { p1, p2 ... },
        transaction: tr);
};
if (connection != null)
{
    A(connection, transaction);
    return;
}

using (var db = new OracleConnection(this.Con_str))
{
    A(db, null);
}

但是对我来说似乎很沉重,我想知道是否有一种更优雅的方式来做到这一点。

谢谢!

我希望我已经足够清楚了,如果没有告诉我。

1 个答案:

答案 0 :(得分:1)

当连接为空时创建新的连接。因此,using语句不会释放连接。

using (var db = connection == null ? new OracleConnection(this.con_str) : null)
{
    return (db ?? connection).Execute(req, new { p1, p2 }, transaction: connection == null ? null : t);
}