我有一个用于访问所有数据库查询的类(数据访问层)。我将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);
}
但是对我来说似乎很沉重,我想知道是否有一种更优雅的方式来做到这一点。
谢谢!
我希望我已经足够清楚了,如果没有告诉我。
答案 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);
}