对于我自己的好奇心,你只是一个简单的问题。我试图不重复我的代码。我还在学习如何正确使用参数和参数,所以我想这将是通过这条路线的,这是我的代码。
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表达式和实体之前,但我没有在我想要的应用程序中使用它。如果我可以将我的查询保存到类文件然后从那里调用它们只是为了使我的代码看起来整洁,那将是很好的。谢谢阅读。
答案 0 :(得分:2)
您可以将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
});
}
}
好处:
SQLConnectionHelper
中并且可以替换,客户端几乎从特定类型的SQL连接中抽象出来(除了SQLiteReader
,可以重写); CustomSQLException
,您只需要在一个地方定义它; SQLConnectionHelper
可以实现IDisposable
并清除连接资源。 这个解决方案可能看起来有点太多&#34;功能性&#34;因为使用高阶函数,你可以用更多的OOP方式重写它,它只是为了给出想法而不是实现。
答案 1 :(得分:1)
一定要将连接字符串设置为一次声明的常量。
private const string DB_CONN_STR = @"Data Source=knowledge.db;Version=3";
你也可以制作一个通用方法来吸引读者:
private SqliteDataReader ExecuteReader(SQLiteConnection lCon, string sql)
{
lCon.Open();
lCmd = new SQLiteCommand(sql, lCon);
return lCmd.ExecuteReader();
}
并像这样使用它:
using(SQLiteConnection lCon = new SQLiteConnection(DB_CONN_STR))
{
SqliteDataReader reader = ExecuteReader(lCon, "SELECT * FROM MyTable");
while(reader.Read())
{
// do stuff...
}
}