每次Connection打开时我都需要执行SQliteCommand。我将继承SQliteConnection类并使用Autofac注册自定义类,但这种方式对我不起作用。
答案 0 :(得分:2)
而不是is a
关系使用has a
关系 - 不要继承SQliteConnection
,而是将其封装在您的类中。
这样的事情应该让你开始:
public class DBHelper
{
private readonly string _connectionString,
_sqlToExecuteOnConnectionOpen;
public DBHelper(string connectionString)
{
_connectionString = connectionString;
_sqlToExecuteOnConnectionOpen = "Your sql goes here";
}
public void ExecuteSql(Action<SQliteConnection> action)
{
using(var con = new SQliteConnection(_connectionString))
{
using(var cmd = new SQliteCommand(_sqlToExecuteOnConnectionOpen, con)
{
con.Open();
// of course, any parameters goes here...
cmd.ExecuteNonQuery();
}
action(con);
}
}
}
现在你有一个方法可以打开并处理SqliteConnection
的实例,执行你的预定义sql,以及你想用该连接执行的任何其他操作。
您甚至可以更进一步,将此方法设为私有,但为ExecuteNonQuery,ExecuteScalar,ExecuteReader公开公共方法,甚至填充数据集或数据表 - 并让它们都执行此方法。 这可以为您节省大量使用ADO.Net时通常编写的重复管道代码。
事实上,我已经发布了一个project on GitHub,它正是这样做的(当然,除了你的常量sql语句) - 你可以克隆它,查看它的代码,并且通常只是从中获取想法并实现它们在你自己的代码中。
答案 1 :(得分:0)
您可以使用AOP原则拦截Open
方法。
让我们从实现您的自定义拦截器开始。
public class PrepareConnectionInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
if (!(invocation.InvocationTarget is IDbConnection
&& invocation.Method.Name == nameof(IDbConnection.Open)))
{
invocation.Proceed();
return;
}
invocation.Proceed();
IDbConnection connection = (IDbConnection)invocation.InvocationTarget;
using(IDbCommand command = connection.CreateCommand())
{
command.CommandText = "SQL statement";
command.ExecuteNonQuery();
}
}
}
然后使用 autofac
注册您的连接和拦截器builder.RegisterType<PrepareConnectionInterceptor>()
.AsSelf();
builder.RegisterType<SQLiteConnection>()
.As<IDbConnection>()
.EnableInterfaceInterceptors()
.InterceptedBy(typeof(PrepareConnectionInterceptor));
现在,每次在已解析的Open
上调用IDbConnection
方法时,都会触发拦截器并执行自定义SQL。