c# - 返回 MySqlDataReader

标签 c# mysql-connector

我想在调用者上返回值,例如我可以使用 asd["columnname"] 但我收到一个错误,示例/代码如下。

我有这个代码

public static MySqlDataReader QueryResultadoMultString(string Query)
    {
        using (var conn = new MySqlConnection(myConnectionString))
        {
            try
            {
                conn.Open();
                var cmd = conn.CreateCommand();
                cmd.CommandText = Query;
                MySqlDataReader myReader = null;
                myReader = cmd.ExecuteReader();
                if (myReader.HasRows)
                {
                    while (myReader.Read())
                    {
                        Console.WriteLine(myReader.GetString(0));
                        return myReader;
                    }
                }

                return myReader;
            }

            catch (MySqlException ex)
            {
                NAPI.Util.ConsoleOutput($"[BaseDados][Erro] {ex.Message}");

                return null;
            }
        }
    }

下面是调用者

var asd = BaseDadosSQL.QueryResultadoMultString($"SELECT `socialclub`,`username`,`password` FROM contas WHERE socialclub = '{player.SocialClubName}'");
Console.WriteLine("Result "+asd["username"]);

我遇到了这个错误

System.Exception: 'No current query in data reader'

最佳答案

所写的方法将迫使您编写极易受到 sql 注入(inject)问题影响的代码。您需要一组单独的参数参数。

你想要更像这样的东西(这也应该解决你问题中的问题):

public static class BaseDadosSQL
{
    private static string connectionString = "connection string here";

    public static IEnumerable<IDataRecord> QueryResult(string Query, params MySqlParameter[] parameters)
    {
        using (var conn = new MySqlConnection(connectionString))
        using (var cmd = new MySqlCommand(Query, conn))
        {
            if (parameters is object && parameters.Length > 0)
            {
                cmd.Parameters.AddRange(parameters);
            }

            conn.Open();
            using (var reader = cmd.ExecuteReader())
            {
                while (reader.Read())
                {
                    yield return reader;
                }
            }
        }
    }
}

然后这样调用它:

//Guessing at type and length here. Use the actual type and length from the database
var p = new MySqlParameter("@SocialClub", MySqlDbType.VarString, 20);
p.Value = player.SocialClubName;
try
{
    var asd = BaseDadosSQL.QueryResult($"SELECT `socialclub`,`username`,`password` FROM contas WHERE socialclub = @SocialClub", p);
    foreach(var result in asd)
    {
        Console.WriteLine("Result " + result["username"]);
    }
}
catch (MySqlException ex)
{
   NAPI.Util.ConsoleOutput($"[BaseDados][Erro] {ex.Message}");
}

此代码将允许您使用包含撇号的 Social Club 名称。 原来的代码会被炸毁。请注意,我还将异常处理移出了数据库代码。

理想情况下,即使是 QueryResult() 方法也应该是 privateBaseDadosSQL 类有一个单独的 public 方法为您需要运行的每个查询。所以它看起来更像这样:

public static class BaseDadosSQL
{
    private static string connectionString = "connection string here";

    private static IEnumerable<IDataRecord> QueryResult(string Query, params MySqlParameter[] parameters)
    {
        using (var conn = new MySqlConnection(connectionString))
        using (var cmd = new MySqlCommand(Query, conn))
        {
            if (parameters is object && parameters.Length > 0)
            {
                cmd.Parameters.AddRange(parameters);
            }

            conn.Open();
            using (var reader = cmd.ExecuteReader())
            {
                while (reader.Read())
                {
                    yield return reader;
                }
            }
        }
    }

    public static IEnumerable<IDataRecord> GetClubLogin(string clubName)
    {
        //Still guessing at type and length here.
        var p = new MySqlParameter("@SocialClub", MySqlDbType.VarString, 20);
        p.Value = clubName;
        return QueryResult($"SELECT `socialclub`,`username`,`password` FROM contas WHERE socialclub = @SocialClub", p); 
    }
}

然后像这样调用:

try
{
    foreach(var result in BaseDadosSQL.GetClubLogin(player.SocialClubName))
    {
        Console.WriteLine("Result " + result["username"]);
    }
}
catch (MySqlException ex)
{
   NAPI.Util.ConsoleOutput($"[BaseDados][Erro] {ex.Message}");
}

最后,像这样存储密码真的真的真的很糟糕。太糟糕了,它甚至不能用于测试/学习/概念代码证明。永远不要那样做!加密存储密码甚至都不行。 加密不够好。

密码应该只存储为固定长度、经过加盐处理的加密(非 MD5)哈希值。当有人尝试登录时,您对尝试的凭据进行加盐和散列处理,然后比较散列值,而不是实际密码。任何其他事情都只是乞求作为最新的大数据泄露事件出现在您选择的报纸的头版。

关于c# - 返回 MySqlDataReader,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59167264/

相关文章:

c# - 使用 C# 进行 selenium webdriver 测试

c# - C# 中的 if/then/else 变量挫折

mysql - 禁用 MySql Connector/Net 的重复架构查找

mysql - 当使用 32 位版本的 MySQL 的 .net 连接器连接到 64 位版本的 MySQL 时,我得到 "Waiting for table metadata lock "

c# - UserControl 中的数据绑定(bind)在设计时不起作用?

c# - 检测一个方法在没有锁的情况下被调用

gradle - 如何从gradle的缓存中复制gradle依赖 jar ?

mysql - Python - Mac OSX 10.10 中的 MySQL 连接器错误

java - 如何在 Eclipse 中使用 MySql 数据库

c# - 如何获取 UI 元素的屏幕位置?