You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#结合SQLite查询数据表列数据的实现及异常处理方法

问题说明

使用DB Browser创建Users.db数据库、手动建立Users表并添加字段后,通过C# SQLite类库查询指定邮箱对应的password字段时,抛出“不应使用TableMapping查询数据”的异常,原实现代码如下:

try
{
  SQLiteConnection conn = new SQLiteConnection("users.db");
  //获取用户在文本框中输入的邮箱地址
  string email = textBox1.Text;
  //定义在数据表上执行的SQL命令文本
  string query = "SELECT password FROM users WHERE email=" + email;
  //定义新的SQLiteCommand对象
  SQLiteCommand command = new SQLiteCommand(conn);
  //设置command对象的查询命令文本
  command.CommandText = query;
  //如何通过command.ExecuteQuery提取返回行中的数据?
  var data = command.ExecuteQuery<TableMapping>();
  if (data != null)
     {
     //尝试获取返回行数据时,SQLite抛出异常,提示不应使用TableMapping查询数据
     }


}catch(SQLiteException exc){
  Console.WriteLine(exc.Message);
}
原代码问题点
  • 资源未正确释放:SQLiteConnection和SQLiteCommand都是非托管资源,没有用using语句包裹,执行完后会出现资源泄漏。
  • SQL写法错误:直接拼接用户输入到SQL语句,既存在SQL注入风险,字符串类型的查询值也没有做转义、加引号处理,本身就存在语法错误;另外代码里写的连接字符串是users.db,和实际创建的Users.db文件名大小写不一致,在区分大小写的文件系统下会直接连错库。
  • 方法调用错误:ExecuteQuery<T>要求传入和查询结果字段匹配的自定义实体类作为泛型参数,TableMapping是SQLite库内部的映射实现类,不能直接作为泛型参数传入使用。
  • 方法选型错误:当前需求是查询匹配条件的单个password字段值,不需要用全结果集映射的查询方法。
正确实现方式

针对当前只需要查询单个字段值的场景,用ExecuteScalar方法配合参数化查询即可,代码如下:

try
{
    // using语句会在代码块执行结束后自动释放连接资源,无需手动调用Close
    using SQLiteConnection conn = new SQLiteConnection("Users.db");
    string email = textBox1.Text.Trim();
    // 用占位符写查询语句,不要拼接用户输入
    string query = "SELECT password FROM users WHERE email = ?";
    // 传入参数创建Command,自动完成参数绑定,避免注入和转义问题
    using SQLiteCommand command = conn.CreateCommand(query, email);
    // ExecuteScalar返回查询结果第一行第一列的值,直接按目标类型转换即可
    string password = command.ExecuteScalar<string>();

    if (!string.IsNullOrEmpty(password))
    {
        // 此处password就是匹配到的密码,可直接做后续校验逻辑
    }
    else
    {
        // 未查询到对应邮箱的记录
    }
}
catch (SQLiteException exc)
{
    Console.WriteLine(exc.Message);
}

如果后续需要查询多列数据、映射到结构化对象,不要使用TableMapping,自行定义和表字段匹配的实体类即可,示例:

// 自定义和表字段对应的实体类,属性名需要和表列名保持一致
public class User
{
    public string Email { get; set; }
    public string Password { get; set; }
}

// 查询时泛型传入自定义的实体类
List<User> queryResult = conn.Query<User>("SELECT email,password FROM users WHERE email = ?", email);

注意:所有涉及用户输入的数据库查询,都要使用参数化传值的方式,禁止直接拼接SQL字符串,避免SQL注入风险,同时也不需要手动处理特殊字符转义、引号包裹的问题。

内容的提问来源于stack exchange,提问作者TechGeek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 22:51:30