【问题标题】:SELECT query returning exception in C# methodSELECT 查询在 C# 方法中返回异常
【发布时间】:2017-12-13 11:49:07
【问题描述】:

我是 C# 和 Npgsql 的新手,我正在尝试在某个表中进行搜索,但遇到了异常。

public User Login(Account c)
{
    User usr = new User();
    using (NpgsqlConnection con = new NpgsqlConnection(strConnection))
    {
        try
        {
            con.Open();
            NpgsqlCommand command = new NpgsqlCommand();
            command.Connection = con;
            command.CommandText = "SELECT name FROM public.user WHERE c_id IN (SELECT id FROM public.account WHERE email=@Email AND password=@Password)";
            command.Parameters.AddWithValue("Email", c.Email);
            command.Parameters.AddWithValue("Password", c.Password);
            NpgsqlDataReader dr = command.ExecuteReader();

            if (dr.HasRows)
            {
                usr.Name = dr["name"].ToString();
            }

        }
        catch (Exception ex)
        {
            throw ex;
        }
    }    
    return usr;
}

以下异常:

System.InvalidOperationException: '没有可用的行'

我做了同样的事情,但使用了 PgAdmin4,而且我只有一行。正是我想要的。

SELECT name FROM public.user WHERE c_id IN (SELECT id FROM public.account WHERE email='user05@gmail.com' AND password='user05');

我该如何解决这个问题?

【问题讨论】:

  • 使用分析器检查正在从 C# 项目执行的确切查询。
  • 在您的底部查询中,您选择了 nome 而不是 name,这是一个错字吗?还有 password vs senha.
  • @EvZ 这不是与数据库相关的异常,而是.net 异常。可能是由于在访问其字段之前未在数据读取器中调用.Read()。检查 styxs 的答案。
  • 您是否希望通过该查询获得不止一行?您可以简单地使用 JOIN 而不是带有子查询的 IN 并使用 ExecuteScalar。也不要为了重新抛出异常而捕获异常。

标签: c# sql npgsql


【解决方案1】:

你必须像这样在dr.Read();时打电话:

if (dr.HasRows)
{
    dr.Read();
    usr.Name = dr["name"].ToString();
}

【讨论】:

  • 没有使用 npgsql,但是在使用 IDataReaders .Close() 之后在其他数据库中应该被调用。看起来像另一个问题。
  • @bradbury9 不需要关闭NpgsqlConnection,因为他使用了using(NpgsqlConnection ... )
  • dr.HasRows 在这里毫无用处,因为dr.Read() 已经返回了一行是否可用或现在......
  • 我指的是关闭 Datareader,using(NpgsqlConnection ... ) 只会关闭连接是可能的。但只要数据读取器既没有显式关闭,也没有在using (IDataReader dr = ...) 内部,那么除了在使用内部之外,连接将保持打开状态。
【解决方案2】:

我建议您使用while 而不是检查HasRows 后跟.Read(),因此代码将如下所示:

while(dr.Read())
{
    usr.Name = dr["name"].ToString();
    // Assign rest of values if there any
}

【讨论】:

  • 我猜只记录了一条记录。
  • 我不建议在很明显的情况下应该只有一行。
  • @Crowcoder:如果你只期望一行,那么为什么不使用TOP 1,如果你只期望一行,我认为没有必要获取N
  • 如果您在循环中一遍又一遍地设置相同的变量,那么这是一个危险信号,它可以在这里工作,但下次 OP 编写查询时它可能会咬他/她。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-31
  • 2015-03-05
  • 2019-07-13
  • 1970-01-01
  • 2019-04-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多