您好,出于我自己的好奇心,我问一个简单的问题。我试图不重复我的代码。我仍在学习如何正确使用参数和参数,所以我想它将通过这条路线,这是我的代码。
public void MultiChoiceLight()
{
lCon = new SQLiteConnection(@"Data Source=knowledge.db;Version=3");
lCon.Open();
string query1 = $"UPDATE testOrder SET question='{QuestionsFromDb.question}', choice1='{QuestionsFromDb.choice1}" +
$"', choice2='{QuestionsFromDb.choice2}', choice3='{QuestionsFromDb.choice3}', choice4='{QuestionsFromDb.choice4}' " +
$"WHERE qid={QuestionsFromDb.b}";
lCmd = new SQLiteCommand(query1, lCon);
lCmd.ExecuteNonQuery();
lDr = lCmd.ExecuteReader();
lCon.Close();
}
public void MultiChoiceButtonNext()
{
lCon = new SQLiteConnection(@"Data Source=knowledge.db;Version=3");
lCon.Open();
string query = $"SELECT * FROM testOrder WHERE qid={qid}";
lCmd = new SQLiteCommand(query, lCon);
lCmd.ExecuteNonQuery();
lDr = lCmd.ExecuteReader();
}
好吧,我想弄清楚的是,每个方法中的代码行仅使用一次,然后输入查询,这样我就可以通过方法尽可能多次地执行此操作。我有很多这样的方法,并且真的很想缩短我的代码。在你说之前,我知道 lambda 表达式和实体,但我没有在我尝试制作的应用程序中使用它。如果我可以将查询保存到类文件中,然后从那里调用它们以使我的代码看起来整洁,那就太好了。谢谢阅读。
最佳答案
您可以将 SQL 连接包装在某种帮助程序类中,无论您需要什么地方:
// TODO: Parametrized queries?
public class SQLConnectionHelper
{
private readonly string _connectionString;
// TODO: Parameterless constructor which gets connection string from config?
public SQLConnectionHelper(string connectionString)
{
_connectionString = connectionString;
}
private TResult WithConnection<T>(Func<SQLiteConnection, TResult> func)
{
// TODO: try-catch-rethrow-finally here
using (var connection = new SQLiteConnection(_connectionString))
{
_sqliteConnection.Open();
var result = func(_sqliteConnection);
_sqliteConnection.Close();
return result;
}
}
public void ConnectExecuteReader(string query, Action<SQLiteDataReader> action)
{
WithConnection(conn => {
var reader = new SQLiteCommand(query, conn).ExecuteReader();
action(reader);
});
}
public int ConnectExecuteNonQuery(string query)
{
return WithConnection(conn => {
return new SQLiteCommand(query, conn).ExecuteNonQuery();
});
}
}
用法:
public class YourClass
{
private readonly SQLConnectionHelper _sql = new SQLConnectionHelper(@"Data Source=knowledge.db;Version=3");
public void MultiChoiceLight()
{
string query1 = $"UPDATE testOrder SET question='{QuestionsFromDb.question}', choice1='{QuestionsFromDb.choice1}" +
$"', choice2='{QuestionsFromDb.choice2}', choice3='{QuestionsFromDb.choice3}', choice4='{QuestionsFromDb.choice4}' " +
$"WHERE qid={QuestionsFromDb.b}";
int result = _sql.ConnectExecuteNonQuery(query1);
}
public void MultiChoiceButtonNext()
{
_sql.ConnectExecuteReader($"SELECT * FROM testOrder WHERE qid={qid}", r => {
// process your reader here, outside of this lambda connection will be closed
});
}
}
好处:
- SQL连接类型被封装在
SQLConnectionHelper
中并且可以被替换,客户端几乎是从特定类型的SQL连接中抽象出来的(除了SQLiteReader
,可以重写); - 封装了SQL连接配置(连接字符串);
- 封装了 SQL 连接错误处理,您可以抛出一些特定的
CustomSQLException
并且只需在一处定义它; - 封装了SQL连接的打开/关闭。例如,您可以拥有一个连接,而不是每次调用都连接,并且只需在一处进行更改;
- 许多其他 OOP 对于维护和 future 可扩展性的好处;
SQLConnectionHelper
可以实现IDisposable
并清理连接资源。
这个解决方案可能看起来有点太“函数式”,因为使用高阶函数,您可以以更 OOP 的方式重写它,它只是为了给出想法,而不是实现。
关于c# - 通过单一方法但使用多个查询的数据库连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43624719/