【问题标题】:SqlDataReader behaving differently between projectsSqlDataReader 在项目之间表现不同
【发布时间】:2013-08-24 23:07:12
【问题描述】:

我的项目是一个 Windows 服务,我无法从我的数据库返回值,所以我将这部分代码分离到一个控制台应用程序中,以便于调试,但在我的服务中不起作用的代码在控制台应用程序。

所以在我的服务中我有这门课

public class DBHandler
{
    public string ReadSQL(string sql)
    {
        try
        {
            using (SqlConnection DBConnection = new SqlConnection(@"Data Source=***;Initial Catalog=***;Integrated Security=True;User ID=***;Password=***"))
            {
                DBConnection.Open();
                SqlCommand DBCommand = new SqlCommand(sql, DBConnection);
                SqlDataReader sqlResults = DBCommand.ExecuteReader();
                if (sqlResults.HasRows)
                {
                    while (sqlResults.Read())
                    {
                        return sqlResults.GetString(0);
                    }
                }
                return sqlResults.HasRows.ToString();
            }
        }
        catch (Exception e)
        {
    return e.ToString();
    }
}

我正在使用类似

DBHandler dbHandler = new DBHandler();
WriteToClientStream(clientStream, dbHandler.ReadSQL(string.Format("SELECT PlayerName FROM Player WHERE PlayerName = '{0}'", UserName)) + "\r\n");

sqlResults.HasRows 返回 false,但同一查询在 SQL Server 和测试控制台应用程序中返回结果

public static void Main(string[] args)
{
    Console.WriteLine(ReadSQL(string.Format("SELECT PlayerName FROM Player WHERE PlayerName = '{0}'", "Hex")));
    Console.ReadLine();
}

public static string ReadSQL(string sql)
{
    try
    {
        using (SqlConnection DBConnection = new SqlConnection(@"Data Source=***;Initial Xatalog=***;Integrated Security=True;User ID=***;Password=***"))
        {
            DBConnection.Open();
            SqlCommand DBCommand = new SqlCommand(sql, DBConnection);
            SqlDataReader sqlResults = DBCommand.ExecuteReader();
            if (sqlResults.HasRows)
            {
                while (sqlResults.Read())
                {
                    return sqlResults.GetString(0);
                }
            }
            return sqlResults.HasRows.ToString();
        }
    }
    catch (Exception e)
    {
        return e.ToString();
    }
}

【问题讨论】:

  • 将调试器附加到服务并单步执行函数时会发生什么?还有一些其他问题/问题:您没有返回IEnumberable<string>,您是否希望从查询中返回多行?如果不是您并且只返回第一列,为什么您应该使用ExecuteScalar() 时使用SqlDataReader?还返回一个字符串而不是让异常冒泡对我来说似乎是奇怪的设计选择。您如何区分有效结果和错误? (当你没有行时返回字符串 "false" 也是如此)
  • 由于某种原因,它不允许我将调试器附加到我的服务进程,这就是为什么我将其拆分为控制台应用程序来测试它的原因。我在使用 ExecuteScalar() 时遇到了类似的问题,这就是为什么我尝试使用 SqlDataReader 之类的东西。 ExecuteScalar() 在控制台应用程序中有效,但在服务中无效。 e.ToString() 返回 System.NullReferenceException:对象引用未设置为对象的实例。在 GWOService.DBHandler.ReadSQL(String sql)
  • 让它也打印e.StackTrace 并获取发生错误的确切行号。然后更新表明您收到NullRefrenceException 和哪一行的问题。

标签: c# sqldatareader


【解决方案1】:

也许问题比你想象的要容易。

如果你在 Service 中尝试与在控制台应用程序中相同的参数会怎样?

所以改变你现有的代码:

   WriteToClientStream(clientStream, dbHandler.ReadSQL(string.Format(
    "SELECT PlayerName FROM Player WHERE PlayerName = '{0}'", UserName)) + "\r\n");

收件人:

WriteToClientStream(clientStream, dbHandler.ReadSQL(string.Format(
"SELECT PlayerName FROM Player WHERE PlayerName = '{0}'", "Hex")));

如果可行,请尝试。

如果是,您可能需要检查您的代码是否正确传递了UserName

【讨论】:

  • 因此,当我将其更改为“十六进制”时,它可以工作。用户名是System.Text.Encoding.UTF8.GetString(message) 而消息是byte[] message = new byte[4096]; 当我一个接一个地输出时,哪个看起来相同?
  • 也许也是因为你最后附加了'"\r\n"'。把这个留在外面。 ;) 你也应该使用参数化查询。 codinghorror.com/blog/2005/04/…
【解决方案2】:

这可能是由于在将byte[] 编码为string 后,字符串末尾出现chars

在运行System.Text.Encoding.UTF8.GetString(message) 后检查以确保没有空终止符或新行等。

例子:

System.Text.Encoding.UTF8.GetString(message).TrimEnd('\0', '\n');

【讨论】:

    猜你喜欢
    • 2015-08-29
    • 2018-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-06
    • 1970-01-01
    相关资源
    最近更新 更多