通过单个方法进行数据库连接,但使用多个查询

时间:2017-04-26 03:52:29

标签: c# database visual-studio

对于我自己的好奇心,你只是一个简单的问题。我试图不重复我的代码。我还在学习如何正确使用参数和参数,所以我想这将是通过这条路线的,这是我的代码。

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表达式和实体之前,但我没有在我想要的应用程序中使用它。如果我可以将我的查询保存到类文件然后从那里调用它们只是为了使我的代码看起来整洁,那将是很好的。谢谢阅读。

2 个答案:

答案 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
        });
    }
}

好处:

  1. SQL连接类型封装在SQLConnectionHelper中并且可以替换,客户端几乎从特定类型的SQL连接中抽象出来(除了SQLiteReader,可以重写);
  2. SQL连接配置(连接字符串)已封装;
  3. 封装SQL连接错误处理,您可以抛出一些特定的CustomSQLException,您只需要在一个地方定义它;
  4. 封装SQL连接打开/关闭。例如,您可以为每个呼叫设置一个连接而不是连接,只需在一个地方进行更改即可;
  5. 许多其他OOP有利于维护和未来的可扩展性;
  6. SQLConnectionHelper可以实现IDisposable并清除连接资源。
  7. 这个解决方案可能看起来有点太多&#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...
    }
}