繁体   English   中英

通过单一方法但使用多个查询的数据库连接

[英]Database connection via a single method but using multiple query

您好,我很想问我一个快速问题。 我试图不重复我的代码。 我仍然在学习如何正确使用参数和参数,所以我想这将是通过这条路线的代码。

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

优点:

  1. SQL连接类型封装在SQLConnectionHelper并且可以替换,客户端几乎是从特定类型的SQL连接中抽象出来的(除了SQLiteReader之外,可以重写);
  2. SQL连接配置(连接字符串)被封装;
  3. SQL连接错误处理是封装的,您可以引发一些特定的CustomSQLException而只需要在一个地方定义即可;
  4. SQL连接的打开/关闭是封装的。 例如,您可以有一个单一的连接,而不是为每个呼叫都建立连接,而只需要在一个位置上进行更改即可;
  5. OOP在维护和将来可扩展性方面还有许多其他好处;
  6. SQLConnectionHelper可以实现IDisposable并清除连接资源。

该解决方案似乎有点“功能化”,因为使用高阶函数,您可以将其重写为更多的OOP方式,其编写只是为了给出想法,而不是实现。

绝对使连接字符串成为一个常量,在某处声明一次。

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...
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM